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"
16*ee02499aSAlex Lorenz #include "CoverageMappingGen.h"
17ef512b99SJustin Bogner #include "clang/AST/RecursiveASTVisitor.h"
18ef512b99SJustin Bogner #include "clang/AST/StmtVisitor.h"
19ef512b99SJustin Bogner #include "llvm/IR/MDBuilder.h"
20837a6f6fSJustin Bogner #include "llvm/ProfileData/InstrProfReader.h"
214bc7731aSDuncan P. N. Exon Smith #include "llvm/Support/Endian.h"
22ef512b99SJustin Bogner #include "llvm/Support/FileSystem.h"
234bc7731aSDuncan P. N. Exon Smith #include "llvm/Support/MD5.h"
24ef512b99SJustin Bogner 
25ef512b99SJustin Bogner using namespace clang;
26ef512b99SJustin Bogner using namespace CodeGen;
27ef512b99SJustin Bogner 
28*ee02499aSAlex Lorenz void CodeGenPGO::setFuncName(StringRef Name,
29*ee02499aSAlex Lorenz                              llvm::GlobalValue::LinkageTypes Linkage) {
30*ee02499aSAlex Lorenz   RawFuncName = Name;
31da1ebedeSBob Wilson 
32da1ebedeSBob Wilson   // Function names may be prefixed with a binary '1' to indicate
33da1ebedeSBob Wilson   // that the backend should not modify the symbols due to any platform
34da1ebedeSBob Wilson   // naming convention. Do not include that '1' in the PGO profile name.
352fe531cbSDuncan P. N. Exon Smith   if (RawFuncName[0] == '\1')
362fe531cbSDuncan P. N. Exon Smith     RawFuncName = RawFuncName.substr(1);
37da1ebedeSBob Wilson 
38*ee02499aSAlex Lorenz   if (!llvm::GlobalValue::isLocalLinkage(Linkage)) {
391b67cfd4SDuncan P. N. Exon Smith     PrefixedFuncName.reset(new std::string(RawFuncName));
40da1ebedeSBob Wilson     return;
41da1ebedeSBob Wilson   }
42da1ebedeSBob Wilson 
43da1ebedeSBob Wilson   // For local symbols, prepend the main file name to distinguish them.
44da1ebedeSBob Wilson   // Do not include the full path in the file name since there's no guarantee
45da1ebedeSBob Wilson   // that it will stay the same, e.g., if the files are checked out from
46da1ebedeSBob Wilson   // version control in different locations.
471b67cfd4SDuncan P. N. Exon Smith   PrefixedFuncName.reset(new std::string(CGM.getCodeGenOpts().MainFileName));
482fe531cbSDuncan P. N. Exon Smith   if (PrefixedFuncName->empty())
492fe531cbSDuncan P. N. Exon Smith     PrefixedFuncName->assign("<unknown>");
502fe531cbSDuncan P. N. Exon Smith   PrefixedFuncName->append(":");
512fe531cbSDuncan P. N. Exon Smith   PrefixedFuncName->append(RawFuncName);
52da1ebedeSBob Wilson }
53da1ebedeSBob Wilson 
54*ee02499aSAlex Lorenz void CodeGenPGO::setFuncName(llvm::Function *Fn) {
55*ee02499aSAlex Lorenz   setFuncName(Fn->getName(), Fn->getLinkage());
56*ee02499aSAlex Lorenz }
57*ee02499aSAlex Lorenz 
58*ee02499aSAlex Lorenz void CodeGenPGO::setVarLinkage(llvm::GlobalValue::LinkageTypes Linkage) {
59*ee02499aSAlex Lorenz   // Set the linkage for variables based on the function linkage.  Usually, we
60*ee02499aSAlex Lorenz   // want to match it, but available_externally and extern_weak both have the
61*ee02499aSAlex Lorenz   // wrong semantics.
62*ee02499aSAlex Lorenz   VarLinkage = Linkage;
63*ee02499aSAlex Lorenz   switch (VarLinkage) {
64*ee02499aSAlex Lorenz   case llvm::GlobalValue::ExternalWeakLinkage:
65*ee02499aSAlex Lorenz     VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;
66*ee02499aSAlex Lorenz     break;
67*ee02499aSAlex Lorenz   case llvm::GlobalValue::AvailableExternallyLinkage:
68*ee02499aSAlex Lorenz     VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage;
69*ee02499aSAlex Lorenz     break;
70*ee02499aSAlex Lorenz   default:
71*ee02499aSAlex Lorenz     break;
72*ee02499aSAlex Lorenz   }
73*ee02499aSAlex Lorenz }
74*ee02499aSAlex Lorenz 
752fe531cbSDuncan P. N. Exon Smith static llvm::Function *getRegisterFunc(CodeGenModule &CGM) {
76a7807637SDuncan P. N. Exon Smith   return CGM.getModule().getFunction("__llvm_profile_register_functions");
772fe531cbSDuncan P. N. Exon Smith }
782fe531cbSDuncan P. N. Exon Smith 
792fe531cbSDuncan P. N. Exon Smith static llvm::BasicBlock *getOrInsertRegisterBB(CodeGenModule &CGM) {
80780443e8SDuncan P. N. Exon Smith   // Don't do this for Darwin.  compiler-rt uses linker magic.
81780443e8SDuncan P. N. Exon Smith   if (CGM.getTarget().getTriple().isOSDarwin())
82780443e8SDuncan P. N. Exon Smith     return nullptr;
83780443e8SDuncan P. N. Exon Smith 
842fe531cbSDuncan P. N. Exon Smith   // Only need to insert this once per module.
852fe531cbSDuncan P. N. Exon Smith   if (llvm::Function *RegisterF = getRegisterFunc(CGM))
862fe531cbSDuncan P. N. Exon Smith     return &RegisterF->getEntryBlock();
872fe531cbSDuncan P. N. Exon Smith 
882fe531cbSDuncan P. N. Exon Smith   // Construct the function.
892fe531cbSDuncan P. N. Exon Smith   auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
902fe531cbSDuncan P. N. Exon Smith   auto *RegisterFTy = llvm::FunctionType::get(VoidTy, false);
912fe531cbSDuncan P. N. Exon Smith   auto *RegisterF = llvm::Function::Create(RegisterFTy,
922fe531cbSDuncan P. N. Exon Smith                                            llvm::GlobalValue::InternalLinkage,
93a7807637SDuncan P. N. Exon Smith                                            "__llvm_profile_register_functions",
942fe531cbSDuncan P. N. Exon Smith                                            &CGM.getModule());
952fe531cbSDuncan P. N. Exon Smith   RegisterF->setUnnamedAddr(true);
962fe531cbSDuncan P. N. Exon Smith   if (CGM.getCodeGenOpts().DisableRedZone)
972fe531cbSDuncan P. N. Exon Smith     RegisterF->addFnAttr(llvm::Attribute::NoRedZone);
982fe531cbSDuncan P. N. Exon Smith 
992fe531cbSDuncan P. N. Exon Smith   // Construct and return the entry block.
1002fe531cbSDuncan P. N. Exon Smith   auto *BB = llvm::BasicBlock::Create(CGM.getLLVMContext(), "", RegisterF);
1012fe531cbSDuncan P. N. Exon Smith   CGBuilderTy Builder(BB);
1022fe531cbSDuncan P. N. Exon Smith   Builder.CreateRetVoid();
1032fe531cbSDuncan P. N. Exon Smith   return BB;
1042fe531cbSDuncan P. N. Exon Smith }
1052fe531cbSDuncan P. N. Exon Smith 
1062fe531cbSDuncan P. N. Exon Smith static llvm::Constant *getOrInsertRuntimeRegister(CodeGenModule &CGM) {
1072fe531cbSDuncan P. N. Exon Smith   auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
1082fe531cbSDuncan P. N. Exon Smith   auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
1092fe531cbSDuncan P. N. Exon Smith   auto *RuntimeRegisterTy = llvm::FunctionType::get(VoidTy, VoidPtrTy, false);
110a7807637SDuncan P. N. Exon Smith   return CGM.getModule().getOrInsertFunction("__llvm_profile_register_function",
1112fe531cbSDuncan P. N. Exon Smith                                              RuntimeRegisterTy);
1122fe531cbSDuncan P. N. Exon Smith }
1132fe531cbSDuncan P. N. Exon Smith 
1147134d47dSDuncan P. N. Exon Smith static bool isMachO(const CodeGenModule &CGM) {
1157134d47dSDuncan P. N. Exon Smith   return CGM.getTarget().getTriple().isOSBinFormatMachO();
1167134d47dSDuncan P. N. Exon Smith }
1177134d47dSDuncan P. N. Exon Smith 
1182fe531cbSDuncan P. N. Exon Smith static StringRef getCountersSection(const CodeGenModule &CGM) {
119a7807637SDuncan P. N. Exon Smith   return isMachO(CGM) ? "__DATA,__llvm_prf_cnts" : "__llvm_prf_cnts";
1202fe531cbSDuncan P. N. Exon Smith }
1212fe531cbSDuncan P. N. Exon Smith 
1222fe531cbSDuncan P. N. Exon Smith static StringRef getNameSection(const CodeGenModule &CGM) {
123a7807637SDuncan P. N. Exon Smith   return isMachO(CGM) ? "__DATA,__llvm_prf_names" : "__llvm_prf_names";
1242fe531cbSDuncan P. N. Exon Smith }
1252fe531cbSDuncan P. N. Exon Smith 
1262fe531cbSDuncan P. N. Exon Smith static StringRef getDataSection(const CodeGenModule &CGM) {
127a7807637SDuncan P. N. Exon Smith   return isMachO(CGM) ? "__DATA,__llvm_prf_data" : "__llvm_prf_data";
1282fe531cbSDuncan P. N. Exon Smith }
1292fe531cbSDuncan P. N. Exon Smith 
1302fe531cbSDuncan P. N. Exon Smith llvm::GlobalVariable *CodeGenPGO::buildDataVar() {
1312fe531cbSDuncan P. N. Exon Smith   // Create name variable.
1322fe531cbSDuncan P. N. Exon Smith   llvm::LLVMContext &Ctx = CGM.getLLVMContext();
1332fe531cbSDuncan P. N. Exon Smith   auto *VarName = llvm::ConstantDataArray::getString(Ctx, getFuncName(),
1342fe531cbSDuncan P. N. Exon Smith                                                      false);
1352fe531cbSDuncan P. N. Exon Smith   auto *Name = new llvm::GlobalVariable(CGM.getModule(), VarName->getType(),
13673f78627SDuncan P. N. Exon Smith                                         true, VarLinkage, VarName,
1372fe531cbSDuncan P. N. Exon Smith                                         getFuncVarName("name"));
1382fe531cbSDuncan P. N. Exon Smith   Name->setSection(getNameSection(CGM));
1392fe531cbSDuncan P. N. Exon Smith   Name->setAlignment(1);
1402fe531cbSDuncan P. N. Exon Smith 
1412fe531cbSDuncan P. N. Exon Smith   // Create data variable.
1422fe531cbSDuncan P. N. Exon Smith   auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
143b4416f58SJustin Bogner   auto *Int64Ty = llvm::Type::getInt64Ty(Ctx);
1442fe531cbSDuncan P. N. Exon Smith   auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
1452fe531cbSDuncan P. N. Exon Smith   auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
146*ee02499aSAlex Lorenz   llvm::GlobalVariable *Data = nullptr;
147*ee02499aSAlex Lorenz   if (RegionCounters) {
1482fe531cbSDuncan P. N. Exon Smith     llvm::Type *DataTypes[] = {
149b4416f58SJustin Bogner       Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy
1502fe531cbSDuncan P. N. Exon Smith     };
1512fe531cbSDuncan P. N. Exon Smith     auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));
1522fe531cbSDuncan P. N. Exon Smith     llvm::Constant *DataVals[] = {
1532fe531cbSDuncan P. N. Exon Smith       llvm::ConstantInt::get(Int32Ty, getFuncName().size()),
1542fe531cbSDuncan P. N. Exon Smith       llvm::ConstantInt::get(Int32Ty, NumRegionCounters),
155b4416f58SJustin Bogner       llvm::ConstantInt::get(Int64Ty, FunctionHash),
1562fe531cbSDuncan P. N. Exon Smith       llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),
1572fe531cbSDuncan P. N. Exon Smith       llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)
1582fe531cbSDuncan P. N. Exon Smith     };
159*ee02499aSAlex Lorenz     Data =
16073f78627SDuncan P. N. Exon Smith       new llvm::GlobalVariable(CGM.getModule(), DataTy, true, VarLinkage,
1612fe531cbSDuncan P. N. Exon Smith                                llvm::ConstantStruct::get(DataTy, DataVals),
1622fe531cbSDuncan P. N. Exon Smith                                getFuncVarName("data"));
1632fe531cbSDuncan P. N. Exon Smith 
1642fe531cbSDuncan P. N. Exon Smith     // All the data should be packed into an array in its own section.
1652fe531cbSDuncan P. N. Exon Smith     Data->setSection(getDataSection(CGM));
1662fe531cbSDuncan P. N. Exon Smith     Data->setAlignment(8);
167*ee02499aSAlex Lorenz   }
168*ee02499aSAlex Lorenz 
169*ee02499aSAlex Lorenz   // Create coverage mapping data variable.
170*ee02499aSAlex Lorenz   if (!CoverageMapping.empty())
171*ee02499aSAlex Lorenz     CGM.getCoverageMapping()->addFunctionMappingRecord(Name,
172*ee02499aSAlex Lorenz                                                        getFuncName().size(),
173*ee02499aSAlex Lorenz                                                        CoverageMapping);
1742fe531cbSDuncan P. N. Exon Smith 
17591212208SDuncan P. N. Exon Smith   // Hide all these symbols so that we correctly get a copy for each
17691212208SDuncan P. N. Exon Smith   // executable.  The profile format expects names and counters to be
17791212208SDuncan P. N. Exon Smith   // contiguous, so references into shared objects would be invalid.
17891212208SDuncan P. N. Exon Smith   if (!llvm::GlobalValue::isLocalLinkage(VarLinkage)) {
17991212208SDuncan P. N. Exon Smith     Name->setVisibility(llvm::GlobalValue::HiddenVisibility);
180*ee02499aSAlex Lorenz     if (Data) {
18191212208SDuncan P. N. Exon Smith       Data->setVisibility(llvm::GlobalValue::HiddenVisibility);
18291212208SDuncan P. N. Exon Smith       RegionCounters->setVisibility(llvm::GlobalValue::HiddenVisibility);
18391212208SDuncan P. N. Exon Smith     }
184*ee02499aSAlex Lorenz   }
18591212208SDuncan P. N. Exon Smith 
1862fe531cbSDuncan P. N. Exon Smith   // Make sure the data doesn't get deleted.
187*ee02499aSAlex Lorenz   if (Data) CGM.addUsedGlobal(Data);
1882fe531cbSDuncan P. N. Exon Smith   return Data;
1892fe531cbSDuncan P. N. Exon Smith }
1902fe531cbSDuncan P. N. Exon Smith 
1912fe531cbSDuncan P. N. Exon Smith void CodeGenPGO::emitInstrumentationData() {
1923212b18bSJustin Bogner   if (!RegionCounters)
193ef512b99SJustin Bogner     return;
194ef512b99SJustin Bogner 
1952fe531cbSDuncan P. N. Exon Smith   // Build the data.
1962fe531cbSDuncan P. N. Exon Smith   auto *Data = buildDataVar();
197ef512b99SJustin Bogner 
1982fe531cbSDuncan P. N. Exon Smith   // Register the data.
199780443e8SDuncan P. N. Exon Smith   auto *RegisterBB = getOrInsertRegisterBB(CGM);
200780443e8SDuncan P. N. Exon Smith   if (!RegisterBB)
201780443e8SDuncan P. N. Exon Smith     return;
202780443e8SDuncan P. N. Exon Smith   CGBuilderTy Builder(RegisterBB->getTerminator());
2032fe531cbSDuncan P. N. Exon Smith   auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
2042fe531cbSDuncan P. N. Exon Smith   Builder.CreateCall(getOrInsertRuntimeRegister(CGM),
2052fe531cbSDuncan P. N. Exon Smith                      Builder.CreateBitCast(Data, VoidPtrTy));
206ef512b99SJustin Bogner }
207ef512b99SJustin Bogner 
208ef512b99SJustin Bogner llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) {
2092fe531cbSDuncan P. N. Exon Smith   if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
210a5f804a7SDuncan P. N. Exon Smith     return nullptr;
211ef512b99SJustin Bogner 
212f2ea775eSJustin Bogner   assert(CGM.getModule().getFunction("__llvm_profile_init") == nullptr &&
213f2ea775eSJustin Bogner          "profile initialization already emitted");
214ef512b99SJustin Bogner 
2155188e91cSDuncan P. N. Exon Smith   // Get the function to call at initialization.
2162fe531cbSDuncan P. N. Exon Smith   llvm::Constant *RegisterF = getRegisterFunc(CGM);
2175188e91cSDuncan P. N. Exon Smith   if (!RegisterF)
218a5f804a7SDuncan P. N. Exon Smith     return nullptr;
2192fe531cbSDuncan P. N. Exon Smith 
2202fe531cbSDuncan P. N. Exon Smith   // Create the initialization function.
2212fe531cbSDuncan P. N. Exon Smith   auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
2222fe531cbSDuncan P. N. Exon Smith   auto *F = llvm::Function::Create(llvm::FunctionType::get(VoidTy, false),
2232fe531cbSDuncan P. N. Exon Smith                                    llvm::GlobalValue::InternalLinkage,
224a7807637SDuncan P. N. Exon Smith                                    "__llvm_profile_init", &CGM.getModule());
225ef512b99SJustin Bogner   F->setUnnamedAddr(true);
226ef512b99SJustin Bogner   F->addFnAttr(llvm::Attribute::NoInline);
227ef512b99SJustin Bogner   if (CGM.getCodeGenOpts().DisableRedZone)
228ef512b99SJustin Bogner     F->addFnAttr(llvm::Attribute::NoRedZone);
229ef512b99SJustin Bogner 
2302fe531cbSDuncan P. N. Exon Smith   // Add the basic block and the necessary calls.
2312fe531cbSDuncan P. N. Exon Smith   CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", F));
2322fe531cbSDuncan P. N. Exon Smith   Builder.CreateCall(RegisterF);
2332fe531cbSDuncan P. N. Exon Smith   Builder.CreateRetVoid();
234ef512b99SJustin Bogner 
235ef512b99SJustin Bogner   return F;
236ef512b99SJustin Bogner }
237ef512b99SJustin Bogner 
238ef512b99SJustin Bogner namespace {
2394bc7731aSDuncan P. N. Exon Smith /// \brief Stable hasher for PGO region counters.
2404bc7731aSDuncan P. N. Exon Smith ///
2414bc7731aSDuncan P. N. Exon Smith /// PGOHash produces a stable hash of a given function's control flow.
2424bc7731aSDuncan P. N. Exon Smith ///
2434bc7731aSDuncan P. N. Exon Smith /// Changing the output of this hash will invalidate all previously generated
2444bc7731aSDuncan P. N. Exon Smith /// profiles -- i.e., don't do it.
2454bc7731aSDuncan P. N. Exon Smith ///
2464bc7731aSDuncan P. N. Exon Smith /// \note  When this hash does eventually change (years?), we still need to
2474bc7731aSDuncan P. N. Exon Smith /// support old hashes.  We'll need to pull in the version number from the
2484bc7731aSDuncan P. N. Exon Smith /// profile data format and use the matching hash function.
2494bc7731aSDuncan P. N. Exon Smith class PGOHash {
2504bc7731aSDuncan P. N. Exon Smith   uint64_t Working;
2514bc7731aSDuncan P. N. Exon Smith   unsigned Count;
2524bc7731aSDuncan P. N. Exon Smith   llvm::MD5 MD5;
2534bc7731aSDuncan P. N. Exon Smith 
2544bc7731aSDuncan P. N. Exon Smith   static const int NumBitsPerType = 6;
2554bc7731aSDuncan P. N. Exon Smith   static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
2564bc7731aSDuncan P. N. Exon Smith   static const unsigned TooBig = 1u << NumBitsPerType;
2574bc7731aSDuncan P. N. Exon Smith 
2584bc7731aSDuncan P. N. Exon Smith public:
2594bc7731aSDuncan P. N. Exon Smith   /// \brief Hash values for AST nodes.
2604bc7731aSDuncan P. N. Exon Smith   ///
2614bc7731aSDuncan P. N. Exon Smith   /// Distinct values for AST nodes that have region counters attached.
2624bc7731aSDuncan P. N. Exon Smith   ///
2634bc7731aSDuncan P. N. Exon Smith   /// These values must be stable.  All new members must be added at the end,
2644bc7731aSDuncan P. N. Exon Smith   /// and no members should be removed.  Changing the enumeration value for an
2654bc7731aSDuncan P. N. Exon Smith   /// AST node will affect the hash of every function that contains that node.
2664bc7731aSDuncan P. N. Exon Smith   enum HashType : unsigned char {
2674bc7731aSDuncan P. N. Exon Smith     None = 0,
2684bc7731aSDuncan P. N. Exon Smith     LabelStmt = 1,
2694bc7731aSDuncan P. N. Exon Smith     WhileStmt,
2704bc7731aSDuncan P. N. Exon Smith     DoStmt,
2714bc7731aSDuncan P. N. Exon Smith     ForStmt,
2724bc7731aSDuncan P. N. Exon Smith     CXXForRangeStmt,
2734bc7731aSDuncan P. N. Exon Smith     ObjCForCollectionStmt,
2744bc7731aSDuncan P. N. Exon Smith     SwitchStmt,
2754bc7731aSDuncan P. N. Exon Smith     CaseStmt,
2764bc7731aSDuncan P. N. Exon Smith     DefaultStmt,
2774bc7731aSDuncan P. N. Exon Smith     IfStmt,
2784bc7731aSDuncan P. N. Exon Smith     CXXTryStmt,
2794bc7731aSDuncan P. N. Exon Smith     CXXCatchStmt,
2804bc7731aSDuncan P. N. Exon Smith     ConditionalOperator,
2814bc7731aSDuncan P. N. Exon Smith     BinaryOperatorLAnd,
2824bc7731aSDuncan P. N. Exon Smith     BinaryOperatorLOr,
2834bc7731aSDuncan P. N. Exon Smith     BinaryConditionalOperator,
2844bc7731aSDuncan P. N. Exon Smith 
2854bc7731aSDuncan P. N. Exon Smith     // Keep this last.  It's for the static assert that follows.
2864bc7731aSDuncan P. N. Exon Smith     LastHashType
2874bc7731aSDuncan P. N. Exon Smith   };
2884bc7731aSDuncan P. N. Exon Smith   static_assert(LastHashType <= TooBig, "Too many types in HashType");
2894bc7731aSDuncan P. N. Exon Smith 
2904bc7731aSDuncan P. N. Exon Smith   // TODO: When this format changes, take in a version number here, and use the
2914bc7731aSDuncan P. N. Exon Smith   // old hash calculation for file formats that used the old hash.
2924bc7731aSDuncan P. N. Exon Smith   PGOHash() : Working(0), Count(0) {}
2934bc7731aSDuncan P. N. Exon Smith   void combine(HashType Type);
2944bc7731aSDuncan P. N. Exon Smith   uint64_t finalize();
2954bc7731aSDuncan P. N. Exon Smith };
2964bc7731aSDuncan P. N. Exon Smith const int PGOHash::NumBitsPerType;
2974bc7731aSDuncan P. N. Exon Smith const unsigned PGOHash::NumTypesPerWord;
2984bc7731aSDuncan P. N. Exon Smith const unsigned PGOHash::TooBig;
2994bc7731aSDuncan P. N. Exon Smith 
300d8931425SBob Wilson   /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
301d8931425SBob Wilson   struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
302ef512b99SJustin Bogner     /// The next counter value to assign.
303ef512b99SJustin Bogner     unsigned NextCounter;
3044bc7731aSDuncan P. N. Exon Smith     /// The function hash.
3054bc7731aSDuncan P. N. Exon Smith     PGOHash Hash;
306ef512b99SJustin Bogner     /// The map of statements to counters.
3073586be72SDuncan P. N. Exon Smith     llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
308ef512b99SJustin Bogner 
3093586be72SDuncan P. N. Exon Smith     MapRegionCounters(llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
3103586be72SDuncan P. N. Exon Smith         : NextCounter(0), CounterMap(CounterMap) {}
311ef512b99SJustin Bogner 
312191ec63bSJustin Bogner     // Blocks and lambdas are handled as separate functions, so we need not
313191ec63bSJustin Bogner     // traverse them in the parent context.
314191ec63bSJustin Bogner     bool TraverseBlockExpr(BlockExpr *BE) { return true; }
315191ec63bSJustin Bogner     bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
31681ab90f7SJustin Bogner     bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
317ef512b99SJustin Bogner 
318d8931425SBob Wilson     bool VisitDecl(const Decl *D) {
319d8931425SBob Wilson       switch (D->getKind()) {
320d8931425SBob Wilson       default:
321d8931425SBob Wilson         break;
322d8931425SBob Wilson       case Decl::Function:
323d8931425SBob Wilson       case Decl::CXXMethod:
324d8931425SBob Wilson       case Decl::CXXConstructor:
325d8931425SBob Wilson       case Decl::CXXDestructor:
326d8931425SBob Wilson       case Decl::CXXConversion:
327d8931425SBob Wilson       case Decl::ObjCMethod:
328d8931425SBob Wilson       case Decl::Block:
32981ab90f7SJustin Bogner       case Decl::Captured:
3304a2f5ae8SDuncan P. N. Exon Smith         CounterMap[D->getBody()] = NextCounter++;
331d8931425SBob Wilson         break;
332ef512b99SJustin Bogner       }
333d8931425SBob Wilson       return true;
3345ec8fe19SBob Wilson     }
335d8931425SBob Wilson 
336d8931425SBob Wilson     bool VisitStmt(const Stmt *S) {
3374bc7731aSDuncan P. N. Exon Smith       auto Type = getHashType(S);
3384bc7731aSDuncan P. N. Exon Smith       if (Type == PGOHash::None)
3394bc7731aSDuncan P. N. Exon Smith         return true;
3404bc7731aSDuncan P. N. Exon Smith 
3414bc7731aSDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
3424bc7731aSDuncan P. N. Exon Smith       Hash.combine(Type);
3434bc7731aSDuncan P. N. Exon Smith       return true;
3444bc7731aSDuncan P. N. Exon Smith     }
3454bc7731aSDuncan P. N. Exon Smith     PGOHash::HashType getHashType(const Stmt *S) {
346d8931425SBob Wilson       switch (S->getStmtClass()) {
347d8931425SBob Wilson       default:
348d8931425SBob Wilson         break;
349d8931425SBob Wilson       case Stmt::LabelStmtClass:
3504bc7731aSDuncan P. N. Exon Smith         return PGOHash::LabelStmt;
351d8931425SBob Wilson       case Stmt::WhileStmtClass:
3524bc7731aSDuncan P. N. Exon Smith         return PGOHash::WhileStmt;
353d8931425SBob Wilson       case Stmt::DoStmtClass:
3544bc7731aSDuncan P. N. Exon Smith         return PGOHash::DoStmt;
355d8931425SBob Wilson       case Stmt::ForStmtClass:
3564bc7731aSDuncan P. N. Exon Smith         return PGOHash::ForStmt;
357d8931425SBob Wilson       case Stmt::CXXForRangeStmtClass:
3584bc7731aSDuncan P. N. Exon Smith         return PGOHash::CXXForRangeStmt;
359d8931425SBob Wilson       case Stmt::ObjCForCollectionStmtClass:
3604bc7731aSDuncan P. N. Exon Smith         return PGOHash::ObjCForCollectionStmt;
361d8931425SBob Wilson       case Stmt::SwitchStmtClass:
3624bc7731aSDuncan P. N. Exon Smith         return PGOHash::SwitchStmt;
363d8931425SBob Wilson       case Stmt::CaseStmtClass:
3644bc7731aSDuncan P. N. Exon Smith         return PGOHash::CaseStmt;
365d8931425SBob Wilson       case Stmt::DefaultStmtClass:
3664bc7731aSDuncan P. N. Exon Smith         return PGOHash::DefaultStmt;
367d8931425SBob Wilson       case Stmt::IfStmtClass:
3684bc7731aSDuncan P. N. Exon Smith         return PGOHash::IfStmt;
369d8931425SBob Wilson       case Stmt::CXXTryStmtClass:
3704bc7731aSDuncan P. N. Exon Smith         return PGOHash::CXXTryStmt;
371d8931425SBob Wilson       case Stmt::CXXCatchStmtClass:
3724bc7731aSDuncan P. N. Exon Smith         return PGOHash::CXXCatchStmt;
373d8931425SBob Wilson       case Stmt::ConditionalOperatorClass:
3744bc7731aSDuncan P. N. Exon Smith         return PGOHash::ConditionalOperator;
375d8931425SBob Wilson       case Stmt::BinaryConditionalOperatorClass:
3764bc7731aSDuncan P. N. Exon Smith         return PGOHash::BinaryConditionalOperator;
377d8931425SBob Wilson       case Stmt::BinaryOperatorClass: {
378d8931425SBob Wilson         const BinaryOperator *BO = cast<BinaryOperator>(S);
3794bc7731aSDuncan P. N. Exon Smith         if (BO->getOpcode() == BO_LAnd)
3804bc7731aSDuncan P. N. Exon Smith           return PGOHash::BinaryOperatorLAnd;
3814bc7731aSDuncan P. N. Exon Smith         if (BO->getOpcode() == BO_LOr)
3824bc7731aSDuncan P. N. Exon Smith           return PGOHash::BinaryOperatorLOr;
383d8931425SBob Wilson         break;
384ef512b99SJustin Bogner       }
385ef512b99SJustin Bogner       }
3864bc7731aSDuncan P. N. Exon Smith       return PGOHash::None;
387ef512b99SJustin Bogner     }
388ef512b99SJustin Bogner   };
389bf854f0fSBob Wilson 
390bf854f0fSBob Wilson   /// A StmtVisitor that propagates the raw counts through the AST and
391bf854f0fSBob Wilson   /// records the count at statements where the value may change.
392bf854f0fSBob Wilson   struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
393bf854f0fSBob Wilson     /// PGO state.
394bf854f0fSBob Wilson     CodeGenPGO &PGO;
395bf854f0fSBob Wilson 
396bf854f0fSBob Wilson     /// A flag that is set when the current count should be recorded on the
397bf854f0fSBob Wilson     /// next statement, such as at the exit of a loop.
398bf854f0fSBob Wilson     bool RecordNextStmtCount;
399bf854f0fSBob Wilson 
400bf854f0fSBob Wilson     /// The map of statements to count values.
4013586be72SDuncan P. N. Exon Smith     llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
402bf854f0fSBob Wilson 
403bf854f0fSBob Wilson     /// BreakContinueStack - Keep counts of breaks and continues inside loops.
404bf854f0fSBob Wilson     struct BreakContinue {
405bf854f0fSBob Wilson       uint64_t BreakCount;
406bf854f0fSBob Wilson       uint64_t ContinueCount;
407bf854f0fSBob Wilson       BreakContinue() : BreakCount(0), ContinueCount(0) {}
408bf854f0fSBob Wilson     };
409bf854f0fSBob Wilson     SmallVector<BreakContinue, 8> BreakContinueStack;
410bf854f0fSBob Wilson 
4113586be72SDuncan P. N. Exon Smith     ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
4123586be72SDuncan P. N. Exon Smith                         CodeGenPGO &PGO)
4133586be72SDuncan P. N. Exon Smith         : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
414bf854f0fSBob Wilson 
415bf854f0fSBob Wilson     void RecordStmtCount(const Stmt *S) {
416bf854f0fSBob Wilson       if (RecordNextStmtCount) {
4173586be72SDuncan P. N. Exon Smith         CountMap[S] = PGO.getCurrentRegionCount();
418bf854f0fSBob Wilson         RecordNextStmtCount = false;
419bf854f0fSBob Wilson       }
420bf854f0fSBob Wilson     }
421bf854f0fSBob Wilson 
422bf854f0fSBob Wilson     void VisitStmt(const Stmt *S) {
423bf854f0fSBob Wilson       RecordStmtCount(S);
424bf854f0fSBob Wilson       for (Stmt::const_child_range I = S->children(); I; ++I) {
425bf854f0fSBob Wilson         if (*I)
426bf854f0fSBob Wilson          this->Visit(*I);
427bf854f0fSBob Wilson       }
428bf854f0fSBob Wilson     }
429bf854f0fSBob Wilson 
4304a2f5ae8SDuncan P. N. Exon Smith     void VisitFunctionDecl(const FunctionDecl *D) {
431d8931425SBob Wilson       // Counter tracks entry to the function body.
4324a2f5ae8SDuncan P. N. Exon Smith       RegionCounter Cnt(PGO, D->getBody());
433bf854f0fSBob Wilson       Cnt.beginRegion();
4344a2f5ae8SDuncan P. N. Exon Smith       CountMap[D->getBody()] = PGO.getCurrentRegionCount();
4354a2f5ae8SDuncan P. N. Exon Smith       Visit(D->getBody());
436bf854f0fSBob Wilson     }
437bf854f0fSBob Wilson 
438191ec63bSJustin Bogner     // Skip lambda expressions. We visit these as FunctionDecls when we're
439191ec63bSJustin Bogner     // generating them and aren't interested in the body when generating a
440191ec63bSJustin Bogner     // parent context.
441191ec63bSJustin Bogner     void VisitLambdaExpr(const LambdaExpr *LE) {}
442191ec63bSJustin Bogner 
44381ab90f7SJustin Bogner     void VisitCapturedDecl(const CapturedDecl *D) {
44481ab90f7SJustin Bogner       // Counter tracks entry to the capture body.
44581ab90f7SJustin Bogner       RegionCounter Cnt(PGO, D->getBody());
44681ab90f7SJustin Bogner       Cnt.beginRegion();
44781ab90f7SJustin Bogner       CountMap[D->getBody()] = PGO.getCurrentRegionCount();
44881ab90f7SJustin Bogner       Visit(D->getBody());
44981ab90f7SJustin Bogner     }
45081ab90f7SJustin Bogner 
4514a2f5ae8SDuncan P. N. Exon Smith     void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
452d8931425SBob Wilson       // Counter tracks entry to the method body.
4534a2f5ae8SDuncan P. N. Exon Smith       RegionCounter Cnt(PGO, D->getBody());
4545ec8fe19SBob Wilson       Cnt.beginRegion();
4554a2f5ae8SDuncan P. N. Exon Smith       CountMap[D->getBody()] = PGO.getCurrentRegionCount();
4564a2f5ae8SDuncan P. N. Exon Smith       Visit(D->getBody());
4575ec8fe19SBob Wilson     }
4585ec8fe19SBob Wilson 
4594a2f5ae8SDuncan P. N. Exon Smith     void VisitBlockDecl(const BlockDecl *D) {
460d8931425SBob Wilson       // Counter tracks entry to the block body.
4614a2f5ae8SDuncan P. N. Exon Smith       RegionCounter Cnt(PGO, D->getBody());
462c845c00aSBob Wilson       Cnt.beginRegion();
4634a2f5ae8SDuncan P. N. Exon Smith       CountMap[D->getBody()] = PGO.getCurrentRegionCount();
4644a2f5ae8SDuncan P. N. Exon Smith       Visit(D->getBody());
465c845c00aSBob Wilson     }
466c845c00aSBob Wilson 
467bf854f0fSBob Wilson     void VisitReturnStmt(const ReturnStmt *S) {
468bf854f0fSBob Wilson       RecordStmtCount(S);
469bf854f0fSBob Wilson       if (S->getRetValue())
470bf854f0fSBob Wilson         Visit(S->getRetValue());
471bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
472bf854f0fSBob Wilson       RecordNextStmtCount = true;
473bf854f0fSBob Wilson     }
474bf854f0fSBob Wilson 
475bf854f0fSBob Wilson     void VisitGotoStmt(const GotoStmt *S) {
476bf854f0fSBob Wilson       RecordStmtCount(S);
477bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
478bf854f0fSBob Wilson       RecordNextStmtCount = true;
479bf854f0fSBob Wilson     }
480bf854f0fSBob Wilson 
481bf854f0fSBob Wilson     void VisitLabelStmt(const LabelStmt *S) {
482bf854f0fSBob Wilson       RecordNextStmtCount = false;
483d8931425SBob Wilson       // Counter tracks the block following the label.
484bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
485bf854f0fSBob Wilson       Cnt.beginRegion();
4863586be72SDuncan P. N. Exon Smith       CountMap[S] = PGO.getCurrentRegionCount();
487bf854f0fSBob Wilson       Visit(S->getSubStmt());
488bf854f0fSBob Wilson     }
489bf854f0fSBob Wilson 
490bf854f0fSBob Wilson     void VisitBreakStmt(const BreakStmt *S) {
491bf854f0fSBob Wilson       RecordStmtCount(S);
492bf854f0fSBob Wilson       assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
493bf854f0fSBob Wilson       BreakContinueStack.back().BreakCount += PGO.getCurrentRegionCount();
494bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
495bf854f0fSBob Wilson       RecordNextStmtCount = true;
496bf854f0fSBob Wilson     }
497bf854f0fSBob Wilson 
498bf854f0fSBob Wilson     void VisitContinueStmt(const ContinueStmt *S) {
499bf854f0fSBob Wilson       RecordStmtCount(S);
500bf854f0fSBob Wilson       assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
501bf854f0fSBob Wilson       BreakContinueStack.back().ContinueCount += PGO.getCurrentRegionCount();
502bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
503bf854f0fSBob Wilson       RecordNextStmtCount = true;
504bf854f0fSBob Wilson     }
505bf854f0fSBob Wilson 
506bf854f0fSBob Wilson     void VisitWhileStmt(const WhileStmt *S) {
507bf854f0fSBob Wilson       RecordStmtCount(S);
508d8931425SBob Wilson       // Counter tracks the body of the loop.
509bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
510bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
511bf854f0fSBob Wilson       // Visit the body region first so the break/continue adjustments can be
512bf854f0fSBob Wilson       // included when visiting the condition.
513bf854f0fSBob Wilson       Cnt.beginRegion();
5143586be72SDuncan P. N. Exon Smith       CountMap[S->getBody()] = PGO.getCurrentRegionCount();
515bf854f0fSBob Wilson       Visit(S->getBody());
516bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
517bf854f0fSBob Wilson 
518bf854f0fSBob Wilson       // ...then go back and propagate counts through the condition. The count
519bf854f0fSBob Wilson       // at the start of the condition is the sum of the incoming edges,
520bf854f0fSBob Wilson       // the backedge from the end of the loop body, and the edges from
521bf854f0fSBob Wilson       // continue statements.
522bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
523bf854f0fSBob Wilson       Cnt.setCurrentRegionCount(Cnt.getParentCount() +
524bf854f0fSBob Wilson                                 Cnt.getAdjustedCount() + BC.ContinueCount);
5253586be72SDuncan P. N. Exon Smith       CountMap[S->getCond()] = PGO.getCurrentRegionCount();
526bf854f0fSBob Wilson       Visit(S->getCond());
527bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
528bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
529bf854f0fSBob Wilson       RecordNextStmtCount = true;
530bf854f0fSBob Wilson     }
531bf854f0fSBob Wilson 
532bf854f0fSBob Wilson     void VisitDoStmt(const DoStmt *S) {
533bf854f0fSBob Wilson       RecordStmtCount(S);
534d8931425SBob Wilson       // Counter tracks the body of the loop.
535bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
536bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
537bf854f0fSBob Wilson       Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
5383586be72SDuncan P. N. Exon Smith       CountMap[S->getBody()] = PGO.getCurrentRegionCount();
539bf854f0fSBob Wilson       Visit(S->getBody());
540bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
541bf854f0fSBob Wilson 
542bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
543bf854f0fSBob Wilson       // The count at the start of the condition is equal to the count at the
544bf854f0fSBob Wilson       // end of the body. The adjusted count does not include either the
545bf854f0fSBob Wilson       // fall-through count coming into the loop or the continue count, so add
546bf854f0fSBob Wilson       // both of those separately. This is coincidentally the same equation as
547bf854f0fSBob Wilson       // with while loops but for different reasons.
548bf854f0fSBob Wilson       Cnt.setCurrentRegionCount(Cnt.getParentCount() +
549bf854f0fSBob Wilson                                 Cnt.getAdjustedCount() + BC.ContinueCount);
5503586be72SDuncan P. N. Exon Smith       CountMap[S->getCond()] = PGO.getCurrentRegionCount();
551bf854f0fSBob Wilson       Visit(S->getCond());
552bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
553bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
554bf854f0fSBob Wilson       RecordNextStmtCount = true;
555bf854f0fSBob Wilson     }
556bf854f0fSBob Wilson 
557bf854f0fSBob Wilson     void VisitForStmt(const ForStmt *S) {
558bf854f0fSBob Wilson       RecordStmtCount(S);
559bf854f0fSBob Wilson       if (S->getInit())
560bf854f0fSBob Wilson         Visit(S->getInit());
561d8931425SBob Wilson       // Counter tracks the body of the loop.
562bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
563bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
564bf854f0fSBob Wilson       // Visit the body region first. (This is basically the same as a while
565bf854f0fSBob Wilson       // loop; see further comments in VisitWhileStmt.)
566bf854f0fSBob Wilson       Cnt.beginRegion();
5673586be72SDuncan P. N. Exon Smith       CountMap[S->getBody()] = PGO.getCurrentRegionCount();
568bf854f0fSBob Wilson       Visit(S->getBody());
569bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
570bf854f0fSBob Wilson 
571bf854f0fSBob Wilson       // The increment is essentially part of the body but it needs to include
572bf854f0fSBob Wilson       // the count for all the continue statements.
573bf854f0fSBob Wilson       if (S->getInc()) {
574bf854f0fSBob Wilson         Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
575bf854f0fSBob Wilson                                   BreakContinueStack.back().ContinueCount);
5763586be72SDuncan P. N. Exon Smith         CountMap[S->getInc()] = PGO.getCurrentRegionCount();
577bf854f0fSBob Wilson         Visit(S->getInc());
578bf854f0fSBob Wilson         Cnt.adjustForControlFlow();
579bf854f0fSBob Wilson       }
580bf854f0fSBob Wilson 
581bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
582bf854f0fSBob Wilson 
583bf854f0fSBob Wilson       // ...then go back and propagate counts through the condition.
584bf854f0fSBob Wilson       if (S->getCond()) {
585bf854f0fSBob Wilson         Cnt.setCurrentRegionCount(Cnt.getParentCount() +
586bf854f0fSBob Wilson                                   Cnt.getAdjustedCount() +
587bf854f0fSBob Wilson                                   BC.ContinueCount);
5883586be72SDuncan P. N. Exon Smith         CountMap[S->getCond()] = PGO.getCurrentRegionCount();
589bf854f0fSBob Wilson         Visit(S->getCond());
590bf854f0fSBob Wilson         Cnt.adjustForControlFlow();
591bf854f0fSBob Wilson       }
592bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
593bf854f0fSBob Wilson       RecordNextStmtCount = true;
594bf854f0fSBob Wilson     }
595bf854f0fSBob Wilson 
596bf854f0fSBob Wilson     void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
597bf854f0fSBob Wilson       RecordStmtCount(S);
598bf854f0fSBob Wilson       Visit(S->getRangeStmt());
599bf854f0fSBob Wilson       Visit(S->getBeginEndStmt());
600d8931425SBob Wilson       // Counter tracks the body of the loop.
601bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
602bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
603bf854f0fSBob Wilson       // Visit the body region first. (This is basically the same as a while
604bf854f0fSBob Wilson       // loop; see further comments in VisitWhileStmt.)
605bf854f0fSBob Wilson       Cnt.beginRegion();
6063586be72SDuncan P. N. Exon Smith       CountMap[S->getLoopVarStmt()] = PGO.getCurrentRegionCount();
607bf854f0fSBob Wilson       Visit(S->getLoopVarStmt());
608bf854f0fSBob Wilson       Visit(S->getBody());
609bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
610bf854f0fSBob Wilson 
611bf854f0fSBob Wilson       // The increment is essentially part of the body but it needs to include
612bf854f0fSBob Wilson       // the count for all the continue statements.
613bf854f0fSBob Wilson       Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
614bf854f0fSBob Wilson                                 BreakContinueStack.back().ContinueCount);
6153586be72SDuncan P. N. Exon Smith       CountMap[S->getInc()] = PGO.getCurrentRegionCount();
616bf854f0fSBob Wilson       Visit(S->getInc());
617bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
618bf854f0fSBob Wilson 
619bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
620bf854f0fSBob Wilson 
621bf854f0fSBob Wilson       // ...then go back and propagate counts through the condition.
622bf854f0fSBob Wilson       Cnt.setCurrentRegionCount(Cnt.getParentCount() +
623bf854f0fSBob Wilson                                 Cnt.getAdjustedCount() +
624bf854f0fSBob Wilson                                 BC.ContinueCount);
6253586be72SDuncan P. N. Exon Smith       CountMap[S->getCond()] = PGO.getCurrentRegionCount();
626bf854f0fSBob Wilson       Visit(S->getCond());
627bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
628bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
629bf854f0fSBob Wilson       RecordNextStmtCount = true;
630bf854f0fSBob Wilson     }
631bf854f0fSBob Wilson 
632bf854f0fSBob Wilson     void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
633bf854f0fSBob Wilson       RecordStmtCount(S);
634bf854f0fSBob Wilson       Visit(S->getElement());
635d8931425SBob Wilson       // Counter tracks the body of the loop.
636bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
637bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
638bf854f0fSBob Wilson       Cnt.beginRegion();
6393586be72SDuncan P. N. Exon Smith       CountMap[S->getBody()] = PGO.getCurrentRegionCount();
640bf854f0fSBob Wilson       Visit(S->getBody());
641bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
642bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
643bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
644bf854f0fSBob Wilson       RecordNextStmtCount = true;
645bf854f0fSBob Wilson     }
646bf854f0fSBob Wilson 
647bf854f0fSBob Wilson     void VisitSwitchStmt(const SwitchStmt *S) {
648bf854f0fSBob Wilson       RecordStmtCount(S);
649bf854f0fSBob Wilson       Visit(S->getCond());
650bf854f0fSBob Wilson       PGO.setCurrentRegionUnreachable();
651bf854f0fSBob Wilson       BreakContinueStack.push_back(BreakContinue());
652bf854f0fSBob Wilson       Visit(S->getBody());
653bf854f0fSBob Wilson       // If the switch is inside a loop, add the continue counts.
654bf854f0fSBob Wilson       BreakContinue BC = BreakContinueStack.pop_back_val();
655bf854f0fSBob Wilson       if (!BreakContinueStack.empty())
656bf854f0fSBob Wilson         BreakContinueStack.back().ContinueCount += BC.ContinueCount;
657d8931425SBob Wilson       // Counter tracks the exit block of the switch.
658bf854f0fSBob Wilson       RegionCounter ExitCnt(PGO, S);
659bf854f0fSBob Wilson       ExitCnt.beginRegion();
660bf854f0fSBob Wilson       RecordNextStmtCount = true;
661bf854f0fSBob Wilson     }
662bf854f0fSBob Wilson 
663bf854f0fSBob Wilson     void VisitCaseStmt(const CaseStmt *S) {
664bf854f0fSBob Wilson       RecordNextStmtCount = false;
665d8931425SBob Wilson       // Counter for this particular case. This counts only jumps from the
666d8931425SBob Wilson       // switch header and does not include fallthrough from the case before
667d8931425SBob Wilson       // this one.
668bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
669bf854f0fSBob Wilson       Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
6703586be72SDuncan P. N. Exon Smith       CountMap[S] = Cnt.getCount();
671bf854f0fSBob Wilson       RecordNextStmtCount = true;
672bf854f0fSBob Wilson       Visit(S->getSubStmt());
673bf854f0fSBob Wilson     }
674bf854f0fSBob Wilson 
675bf854f0fSBob Wilson     void VisitDefaultStmt(const DefaultStmt *S) {
676bf854f0fSBob Wilson       RecordNextStmtCount = false;
677d8931425SBob Wilson       // Counter for this default case. This does not include fallthrough from
678d8931425SBob Wilson       // the previous case.
679bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
680bf854f0fSBob Wilson       Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
6813586be72SDuncan P. N. Exon Smith       CountMap[S] = Cnt.getCount();
682bf854f0fSBob Wilson       RecordNextStmtCount = true;
683bf854f0fSBob Wilson       Visit(S->getSubStmt());
684bf854f0fSBob Wilson     }
685bf854f0fSBob Wilson 
686bf854f0fSBob Wilson     void VisitIfStmt(const IfStmt *S) {
687bf854f0fSBob Wilson       RecordStmtCount(S);
688d8931425SBob Wilson       // Counter tracks the "then" part of an if statement. The count for
689d8931425SBob Wilson       // the "else" part, if it exists, will be calculated from this counter.
690bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
691bf854f0fSBob Wilson       Visit(S->getCond());
692bf854f0fSBob Wilson 
693bf854f0fSBob Wilson       Cnt.beginRegion();
6943586be72SDuncan P. N. Exon Smith       CountMap[S->getThen()] = PGO.getCurrentRegionCount();
695bf854f0fSBob Wilson       Visit(S->getThen());
696bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
697bf854f0fSBob Wilson 
698bf854f0fSBob Wilson       if (S->getElse()) {
699bf854f0fSBob Wilson         Cnt.beginElseRegion();
7003586be72SDuncan P. N. Exon Smith         CountMap[S->getElse()] = PGO.getCurrentRegionCount();
701bf854f0fSBob Wilson         Visit(S->getElse());
702bf854f0fSBob Wilson         Cnt.adjustForControlFlow();
703bf854f0fSBob Wilson       }
704bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(0);
705bf854f0fSBob Wilson       RecordNextStmtCount = true;
706bf854f0fSBob Wilson     }
707bf854f0fSBob Wilson 
708bf854f0fSBob Wilson     void VisitCXXTryStmt(const CXXTryStmt *S) {
709bf854f0fSBob Wilson       RecordStmtCount(S);
710bf854f0fSBob Wilson       Visit(S->getTryBlock());
711bf854f0fSBob Wilson       for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
712bf854f0fSBob Wilson         Visit(S->getHandler(I));
713d8931425SBob Wilson       // Counter tracks the continuation block of the try statement.
714bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
715bf854f0fSBob Wilson       Cnt.beginRegion();
716bf854f0fSBob Wilson       RecordNextStmtCount = true;
717bf854f0fSBob Wilson     }
718bf854f0fSBob Wilson 
719bf854f0fSBob Wilson     void VisitCXXCatchStmt(const CXXCatchStmt *S) {
720bf854f0fSBob Wilson       RecordNextStmtCount = false;
721d8931425SBob Wilson       // Counter tracks the catch statement's handler block.
722bf854f0fSBob Wilson       RegionCounter Cnt(PGO, S);
723bf854f0fSBob Wilson       Cnt.beginRegion();
7243586be72SDuncan P. N. Exon Smith       CountMap[S] = PGO.getCurrentRegionCount();
725bf854f0fSBob Wilson       Visit(S->getHandlerBlock());
726bf854f0fSBob Wilson     }
727bf854f0fSBob Wilson 
72853c55d99SJustin Bogner     void VisitAbstractConditionalOperator(
72953c55d99SJustin Bogner         const AbstractConditionalOperator *E) {
730bf854f0fSBob Wilson       RecordStmtCount(E);
731d8931425SBob Wilson       // Counter tracks the "true" part of a conditional operator. The
732d8931425SBob Wilson       // count in the "false" part will be calculated from this counter.
733bf854f0fSBob Wilson       RegionCounter Cnt(PGO, E);
734bf854f0fSBob Wilson       Visit(E->getCond());
735bf854f0fSBob Wilson 
736bf854f0fSBob Wilson       Cnt.beginRegion();
7373586be72SDuncan P. N. Exon Smith       CountMap[E->getTrueExpr()] = PGO.getCurrentRegionCount();
738bf854f0fSBob Wilson       Visit(E->getTrueExpr());
739bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
740bf854f0fSBob Wilson 
741bf854f0fSBob Wilson       Cnt.beginElseRegion();
7423586be72SDuncan P. N. Exon Smith       CountMap[E->getFalseExpr()] = PGO.getCurrentRegionCount();
743bf854f0fSBob Wilson       Visit(E->getFalseExpr());
744bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
745bf854f0fSBob Wilson 
746bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(0);
747bf854f0fSBob Wilson       RecordNextStmtCount = true;
748bf854f0fSBob Wilson     }
749bf854f0fSBob Wilson 
750bf854f0fSBob Wilson     void VisitBinLAnd(const BinaryOperator *E) {
751bf854f0fSBob Wilson       RecordStmtCount(E);
752d8931425SBob Wilson       // Counter tracks the right hand side of a logical and operator.
753bf854f0fSBob Wilson       RegionCounter Cnt(PGO, E);
754bf854f0fSBob Wilson       Visit(E->getLHS());
755bf854f0fSBob Wilson       Cnt.beginRegion();
7563586be72SDuncan P. N. Exon Smith       CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
757bf854f0fSBob Wilson       Visit(E->getRHS());
758bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
759bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(0);
760bf854f0fSBob Wilson       RecordNextStmtCount = true;
761bf854f0fSBob Wilson     }
762bf854f0fSBob Wilson 
763bf854f0fSBob Wilson     void VisitBinLOr(const BinaryOperator *E) {
764bf854f0fSBob Wilson       RecordStmtCount(E);
765d8931425SBob Wilson       // Counter tracks the right hand side of a logical or operator.
766bf854f0fSBob Wilson       RegionCounter Cnt(PGO, E);
767bf854f0fSBob Wilson       Visit(E->getLHS());
768bf854f0fSBob Wilson       Cnt.beginRegion();
7693586be72SDuncan P. N. Exon Smith       CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
770bf854f0fSBob Wilson       Visit(E->getRHS());
771bf854f0fSBob Wilson       Cnt.adjustForControlFlow();
772bf854f0fSBob Wilson       Cnt.applyAdjustmentsToRegion(0);
773bf854f0fSBob Wilson       RecordNextStmtCount = true;
774bf854f0fSBob Wilson     }
775bf854f0fSBob Wilson   };
776ef512b99SJustin Bogner }
777ef512b99SJustin Bogner 
7784bc7731aSDuncan P. N. Exon Smith void PGOHash::combine(HashType Type) {
7794bc7731aSDuncan P. N. Exon Smith   // Check that we never combine 0 and only have six bits.
7804bc7731aSDuncan P. N. Exon Smith   assert(Type && "Hash is invalid: unexpected type 0");
7814bc7731aSDuncan P. N. Exon Smith   assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
7824bc7731aSDuncan P. N. Exon Smith 
7834bc7731aSDuncan P. N. Exon Smith   // Pass through MD5 if enough work has built up.
7844bc7731aSDuncan P. N. Exon Smith   if (Count && Count % NumTypesPerWord == 0) {
7854bc7731aSDuncan P. N. Exon Smith     using namespace llvm::support;
7864bc7731aSDuncan P. N. Exon Smith     uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
7874bc7731aSDuncan P. N. Exon Smith     MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
7884bc7731aSDuncan P. N. Exon Smith     Working = 0;
7894bc7731aSDuncan P. N. Exon Smith   }
7904bc7731aSDuncan P. N. Exon Smith 
7914bc7731aSDuncan P. N. Exon Smith   // Accumulate the current type.
7924bc7731aSDuncan P. N. Exon Smith   ++Count;
7934bc7731aSDuncan P. N. Exon Smith   Working = Working << NumBitsPerType | Type;
7944bc7731aSDuncan P. N. Exon Smith }
7954bc7731aSDuncan P. N. Exon Smith 
7964bc7731aSDuncan P. N. Exon Smith uint64_t PGOHash::finalize() {
7974bc7731aSDuncan P. N. Exon Smith   // Use Working as the hash directly if we never used MD5.
7984bc7731aSDuncan P. N. Exon Smith   if (Count <= NumTypesPerWord)
7994bc7731aSDuncan P. N. Exon Smith     // No need to byte swap here, since none of the math was endian-dependent.
8004bc7731aSDuncan P. N. Exon Smith     // This number will be byte-swapped as required on endianness transitions,
8014bc7731aSDuncan P. N. Exon Smith     // so we will see the same value on the other side.
8024bc7731aSDuncan P. N. Exon Smith     return Working;
8034bc7731aSDuncan P. N. Exon Smith 
8044bc7731aSDuncan P. N. Exon Smith   // Check for remaining work in Working.
8054bc7731aSDuncan P. N. Exon Smith   if (Working)
8064bc7731aSDuncan P. N. Exon Smith     MD5.update(Working);
8074bc7731aSDuncan P. N. Exon Smith 
8084bc7731aSDuncan P. N. Exon Smith   // Finalize the MD5 and return the hash.
8094bc7731aSDuncan P. N. Exon Smith   llvm::MD5::MD5Result Result;
8104bc7731aSDuncan P. N. Exon Smith   MD5.final(Result);
8114bc7731aSDuncan P. N. Exon Smith   using namespace llvm::support;
8124bc7731aSDuncan P. N. Exon Smith   return endian::read<uint64_t, little, unaligned>(Result);
8134bc7731aSDuncan P. N. Exon Smith }
8144bc7731aSDuncan P. N. Exon Smith 
815d971cd1bSDuncan P. N. Exon Smith static void emitRuntimeHook(CodeGenModule &CGM) {
8163fefedb2SDuncan P. N. Exon Smith   const char *const RuntimeVarName = "__llvm_profile_runtime";
8173fefedb2SDuncan P. N. Exon Smith   const char *const RuntimeUserName = "__llvm_profile_runtime_user";
818d971cd1bSDuncan P. N. Exon Smith   if (CGM.getModule().getGlobalVariable(RuntimeVarName))
819d971cd1bSDuncan P. N. Exon Smith     return;
820d971cd1bSDuncan P. N. Exon Smith 
821d971cd1bSDuncan P. N. Exon Smith   // Declare the runtime hook.
822d971cd1bSDuncan P. N. Exon Smith   llvm::LLVMContext &Ctx = CGM.getLLVMContext();
823d971cd1bSDuncan P. N. Exon Smith   auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
824d971cd1bSDuncan P. N. Exon Smith   auto *Var = new llvm::GlobalVariable(CGM.getModule(), Int32Ty, false,
825d971cd1bSDuncan P. N. Exon Smith                                        llvm::GlobalValue::ExternalLinkage,
826d971cd1bSDuncan P. N. Exon Smith                                        nullptr, RuntimeVarName);
827d971cd1bSDuncan P. N. Exon Smith 
828d971cd1bSDuncan P. N. Exon Smith   // Make a function that uses it.
829d971cd1bSDuncan P. N. Exon Smith   auto *User = llvm::Function::Create(llvm::FunctionType::get(Int32Ty, false),
830d971cd1bSDuncan P. N. Exon Smith                                       llvm::GlobalValue::LinkOnceODRLinkage,
831d971cd1bSDuncan P. N. Exon Smith                                       RuntimeUserName, &CGM.getModule());
832d971cd1bSDuncan P. N. Exon Smith   User->addFnAttr(llvm::Attribute::NoInline);
833d971cd1bSDuncan P. N. Exon Smith   if (CGM.getCodeGenOpts().DisableRedZone)
834d971cd1bSDuncan P. N. Exon Smith     User->addFnAttr(llvm::Attribute::NoRedZone);
835d971cd1bSDuncan P. N. Exon Smith   CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", User));
836d971cd1bSDuncan P. N. Exon Smith   auto *Load = Builder.CreateLoad(Var);
837d971cd1bSDuncan P. N. Exon Smith   Builder.CreateRet(Load);
838d971cd1bSDuncan P. N. Exon Smith 
839d971cd1bSDuncan P. N. Exon Smith   // Create a use of the function.  Now the definition of the runtime variable
840d971cd1bSDuncan P. N. Exon Smith   // should get pulled in, along with any static initializears.
841d971cd1bSDuncan P. N. Exon Smith   CGM.addUsedGlobal(User);
842d971cd1bSDuncan P. N. Exon Smith }
843d971cd1bSDuncan P. N. Exon Smith 
844*ee02499aSAlex Lorenz void CodeGenPGO::checkGlobalDecl(GlobalDecl GD) {
845*ee02499aSAlex Lorenz   // Make sure we only emit coverage mapping for one constructor/destructor.
846*ee02499aSAlex Lorenz   // Clang emits several functions for the constructor and the destructor of
847*ee02499aSAlex Lorenz   // a class. Every function is instrumented, but we only want to provide
848*ee02499aSAlex Lorenz   // coverage for one of them. Because of that we only emit the coverage mapping
849*ee02499aSAlex Lorenz   // for the base constructor/destructor.
850*ee02499aSAlex Lorenz   if ((isa<CXXConstructorDecl>(GD.getDecl()) &&
851*ee02499aSAlex Lorenz        GD.getCtorType() != Ctor_Base) ||
852*ee02499aSAlex Lorenz       (isa<CXXDestructorDecl>(GD.getDecl()) &&
853*ee02499aSAlex Lorenz        GD.getDtorType() != Dtor_Base)) {
854*ee02499aSAlex Lorenz     SkipCoverageMapping = true;
855*ee02499aSAlex Lorenz   }
856*ee02499aSAlex Lorenz }
857*ee02499aSAlex Lorenz 
858da1ebedeSBob Wilson void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
859ef512b99SJustin Bogner   bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
860837a6f6fSJustin Bogner   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
861837a6f6fSJustin Bogner   if (!InstrumentRegions && !PGOReader)
862ef512b99SJustin Bogner     return;
8633212b18bSJustin Bogner   if (D->isImplicit())
864ef512b99SJustin Bogner     return;
865*ee02499aSAlex Lorenz   CGM.ClearUnusedCoverageMapping(D);
866da1ebedeSBob Wilson   setFuncName(Fn);
867*ee02499aSAlex Lorenz   setVarLinkage(Fn->getLinkage());
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();
873*ee02499aSAlex Lorenz     if (CGM.getCodeGenOpts().CoverageMapping)
874*ee02499aSAlex Lorenz       emitCounterRegionMapping(D);
875d971cd1bSDuncan P. N. Exon Smith   }
876837a6f6fSJustin Bogner   if (PGOReader) {
87740b8ba14SJustin Bogner     SourceManager &SM = CGM.getContext().getSourceManager();
87840b8ba14SJustin Bogner     loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
879bf854f0fSBob Wilson     computeRegionCounts(D);
880837a6f6fSJustin Bogner     applyFunctionAttributes(PGOReader, Fn);
881bf854f0fSBob Wilson   }
882ef512b99SJustin Bogner }
883ef512b99SJustin Bogner 
884ef512b99SJustin Bogner void CodeGenPGO::mapRegionCounters(const Decl *D) {
8851b67cfd4SDuncan P. N. Exon Smith   RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
8863586be72SDuncan P. N. Exon Smith   MapRegionCounters Walker(*RegionCounterMap);
887ef512b99SJustin Bogner   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
888d8931425SBob Wilson     Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
8895ec8fe19SBob Wilson   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
890d8931425SBob Wilson     Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
891c845c00aSBob Wilson   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
892d8931425SBob Wilson     Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
89381ab90f7SJustin Bogner   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
89481ab90f7SJustin Bogner     Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
8953212b18bSJustin Bogner   assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
896ef512b99SJustin Bogner   NumRegionCounters = Walker.NextCounter;
8974bc7731aSDuncan P. N. Exon Smith   FunctionHash = Walker.Hash.finalize();
898ef512b99SJustin Bogner }
899ef512b99SJustin Bogner 
900*ee02499aSAlex Lorenz void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
901*ee02499aSAlex Lorenz   if (SkipCoverageMapping)
902*ee02499aSAlex Lorenz     return;
903*ee02499aSAlex Lorenz   // Don't map the functions inside the system headers
904*ee02499aSAlex Lorenz   auto Loc = D->getBody()->getLocStart();
905*ee02499aSAlex Lorenz   if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))
906*ee02499aSAlex Lorenz     return;
907*ee02499aSAlex Lorenz 
908*ee02499aSAlex Lorenz   llvm::raw_string_ostream OS(CoverageMapping);
909*ee02499aSAlex Lorenz   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
910*ee02499aSAlex Lorenz                                 CGM.getContext().getSourceManager(),
911*ee02499aSAlex Lorenz                                 CGM.getLangOpts(), RegionCounterMap.get(),
912*ee02499aSAlex Lorenz                                 NumRegionCounters);
913*ee02499aSAlex Lorenz   MappingGen.emitCounterMapping(D, OS);
914*ee02499aSAlex Lorenz   OS.flush();
915*ee02499aSAlex Lorenz }
916*ee02499aSAlex Lorenz 
917*ee02499aSAlex Lorenz void
918*ee02499aSAlex Lorenz CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef FuncName,
919*ee02499aSAlex Lorenz                                     llvm::GlobalValue::LinkageTypes Linkage) {
920*ee02499aSAlex Lorenz   if (SkipCoverageMapping)
921*ee02499aSAlex Lorenz     return;
922*ee02499aSAlex Lorenz   setFuncName(FuncName, Linkage);
923*ee02499aSAlex Lorenz   setVarLinkage(Linkage);
924*ee02499aSAlex Lorenz 
925*ee02499aSAlex Lorenz   // Don't map the functions inside the system headers
926*ee02499aSAlex Lorenz   auto Loc = D->getBody()->getLocStart();
927*ee02499aSAlex Lorenz   if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))
928*ee02499aSAlex Lorenz     return;
929*ee02499aSAlex Lorenz 
930*ee02499aSAlex Lorenz   llvm::raw_string_ostream OS(CoverageMapping);
931*ee02499aSAlex Lorenz   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
932*ee02499aSAlex Lorenz                                 CGM.getContext().getSourceManager(),
933*ee02499aSAlex Lorenz                                 CGM.getLangOpts());
934*ee02499aSAlex Lorenz   MappingGen.emitEmptyMapping(D, OS);
935*ee02499aSAlex Lorenz   OS.flush();
936*ee02499aSAlex Lorenz   buildDataVar();
937*ee02499aSAlex Lorenz }
938*ee02499aSAlex Lorenz 
939bf854f0fSBob Wilson void CodeGenPGO::computeRegionCounts(const Decl *D) {
9401b67cfd4SDuncan P. N. Exon Smith   StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
9413586be72SDuncan P. N. Exon Smith   ComputeRegionCounts Walker(*StmtCountMap, *this);
942bf854f0fSBob Wilson   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
943bf854f0fSBob Wilson     Walker.VisitFunctionDecl(FD);
9445ec8fe19SBob Wilson   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
9455ec8fe19SBob Wilson     Walker.VisitObjCMethodDecl(MD);
946c845c00aSBob Wilson   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
947c845c00aSBob Wilson     Walker.VisitBlockDecl(BD);
94881ab90f7SJustin Bogner   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
94981ab90f7SJustin Bogner     Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
950bf854f0fSBob Wilson }
951bf854f0fSBob Wilson 
952837a6f6fSJustin Bogner void
953837a6f6fSJustin Bogner CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
9544c9c45c0SJustin Bogner                                     llvm::Function *Fn) {
9554c9c45c0SJustin Bogner   if (!haveRegionCounts())
9564c9c45c0SJustin Bogner     return;
9574c9c45c0SJustin Bogner 
958837a6f6fSJustin Bogner   uint64_t MaxFunctionCount = PGOReader->getMaximumFunctionCount();
9594c9c45c0SJustin Bogner   uint64_t FunctionCount = getRegionCount(0);
9604c9c45c0SJustin Bogner   if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount))
9614c9c45c0SJustin Bogner     // Turn on InlineHint attribute for hot functions.
9624c9c45c0SJustin Bogner     // FIXME: 30% is from preliminary tuning on SPEC, it may not be optimal.
9634c9c45c0SJustin Bogner     Fn->addFnAttr(llvm::Attribute::InlineHint);
9644c9c45c0SJustin Bogner   else if (FunctionCount <= (uint64_t)(0.01 * (double)MaxFunctionCount))
9654c9c45c0SJustin Bogner     // Turn on Cold attribute for cold functions.
9664c9c45c0SJustin Bogner     // FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal.
9674c9c45c0SJustin Bogner     Fn->addFnAttr(llvm::Attribute::Cold);
9684c9c45c0SJustin Bogner }
9694c9c45c0SJustin Bogner 
970ef512b99SJustin Bogner void CodeGenPGO::emitCounterVariables() {
971ef512b99SJustin Bogner   llvm::LLVMContext &Ctx = CGM.getLLVMContext();
972ef512b99SJustin Bogner   llvm::ArrayType *CounterTy = llvm::ArrayType::get(llvm::Type::getInt64Ty(Ctx),
973ef512b99SJustin Bogner                                                     NumRegionCounters);
974ef512b99SJustin Bogner   RegionCounters =
97573f78627SDuncan P. N. Exon Smith     new llvm::GlobalVariable(CGM.getModule(), CounterTy, false, VarLinkage,
976ef512b99SJustin Bogner                              llvm::Constant::getNullValue(CounterTy),
9772fe531cbSDuncan P. N. Exon Smith                              getFuncVarName("counters"));
9782fe531cbSDuncan P. N. Exon Smith   RegionCounters->setAlignment(8);
9792fe531cbSDuncan P. N. Exon Smith   RegionCounters->setSection(getCountersSection(CGM));
980ef512b99SJustin Bogner }
981ef512b99SJustin Bogner 
982ef512b99SJustin Bogner void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) {
983749ebc7fSBob Wilson   if (!RegionCounters)
984ef512b99SJustin Bogner     return;
985ef512b99SJustin Bogner   llvm::Value *Addr =
986ef512b99SJustin Bogner     Builder.CreateConstInBoundsGEP2_64(RegionCounters, 0, Counter);
987ef512b99SJustin Bogner   llvm::Value *Count = Builder.CreateLoad(Addr, "pgocount");
988ef512b99SJustin Bogner   Count = Builder.CreateAdd(Count, Builder.getInt64(1));
989ef512b99SJustin Bogner   Builder.CreateStore(Count, Addr);
990ef512b99SJustin Bogner }
991ef512b99SJustin Bogner 
99240b8ba14SJustin Bogner void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
99340b8ba14SJustin Bogner                                   bool IsInMainFile) {
99440b8ba14SJustin Bogner   CGM.getPGOStats().addVisited(IsInMainFile);
9951b67cfd4SDuncan P. N. Exon Smith   RegionCounts.reset(new std::vector<uint64_t>);
9969c6818efSJustin Bogner   if (std::error_code EC = PGOReader->getFunctionCounts(
9979c6818efSJustin Bogner           getFuncName(), FunctionHash, *RegionCounts)) {
9989c6818efSJustin Bogner     if (EC == llvm::instrprof_error::unknown_function)
99940b8ba14SJustin Bogner       CGM.getPGOStats().addMissing(IsInMainFile);
10009c6818efSJustin Bogner     else if (EC == llvm::instrprof_error::hash_mismatch)
10019c6818efSJustin Bogner       CGM.getPGOStats().addMismatched(IsInMainFile);
10029c6818efSJustin Bogner     else if (EC == llvm::instrprof_error::malformed)
10039c6818efSJustin Bogner       // TODO: Consider a more specific warning for this case.
100440b8ba14SJustin Bogner       CGM.getPGOStats().addMismatched(IsInMainFile);
1005e2ef2a09SJustin Bogner     RegionCounts.reset();
1006e2ef2a09SJustin Bogner   }
1007ef512b99SJustin Bogner }
1008ef512b99SJustin Bogner 
1009ef512b99SJustin Bogner void CodeGenPGO::destroyRegionCounters() {
10101b67cfd4SDuncan P. N. Exon Smith   RegionCounterMap.reset();
10111b67cfd4SDuncan P. N. Exon Smith   StmtCountMap.reset();
10121b67cfd4SDuncan P. N. Exon Smith   RegionCounts.reset();
10133212b18bSJustin Bogner   RegionCounters = nullptr;
1014ef512b99SJustin Bogner }
1015ef512b99SJustin Bogner 
101638402dc9SDuncan P. N. Exon Smith /// \brief Calculate what to divide by to scale weights.
101738402dc9SDuncan P. N. Exon Smith ///
101838402dc9SDuncan P. N. Exon Smith /// Given the maximum weight, calculate a divisor that will scale all the
101938402dc9SDuncan P. N. Exon Smith /// weights to strictly less than UINT32_MAX.
102038402dc9SDuncan P. N. Exon Smith static uint64_t calculateWeightScale(uint64_t MaxWeight) {
102138402dc9SDuncan P. N. Exon Smith   return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
102238402dc9SDuncan P. N. Exon Smith }
102338402dc9SDuncan P. N. Exon Smith 
102438402dc9SDuncan P. N. Exon Smith /// \brief Scale an individual branch weight (and add 1).
102538402dc9SDuncan P. N. Exon Smith ///
102638402dc9SDuncan P. N. Exon Smith /// Scale a 64-bit weight down to 32-bits using \c Scale.
102738402dc9SDuncan P. N. Exon Smith ///
102838402dc9SDuncan P. N. Exon Smith /// According to Laplace's Rule of Succession, it is better to compute the
102938402dc9SDuncan P. N. Exon Smith /// weight based on the count plus 1, so universally add 1 to the value.
103038402dc9SDuncan P. N. Exon Smith ///
103138402dc9SDuncan P. N. Exon Smith /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
103238402dc9SDuncan P. N. Exon Smith /// greater than \c Weight.
103338402dc9SDuncan P. N. Exon Smith static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
103438402dc9SDuncan P. N. Exon Smith   assert(Scale && "scale by 0?");
103538402dc9SDuncan P. N. Exon Smith   uint64_t Scaled = Weight / Scale + 1;
103638402dc9SDuncan P. N. Exon Smith   assert(Scaled <= UINT32_MAX && "overflow 32-bits");
103738402dc9SDuncan P. N. Exon Smith   return Scaled;
103838402dc9SDuncan P. N. Exon Smith }
103938402dc9SDuncan P. N. Exon Smith 
1040ef512b99SJustin Bogner llvm::MDNode *CodeGenPGO::createBranchWeights(uint64_t TrueCount,
1041ef512b99SJustin Bogner                                               uint64_t FalseCount) {
104238402dc9SDuncan P. N. Exon Smith   // Check for empty weights.
1043ef512b99SJustin Bogner   if (!TrueCount && !FalseCount)
1044a5f804a7SDuncan P. N. Exon Smith     return nullptr;
1045ef512b99SJustin Bogner 
104638402dc9SDuncan P. N. Exon Smith   // Calculate how to scale down to 32-bits.
104738402dc9SDuncan P. N. Exon Smith   uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
104838402dc9SDuncan P. N. Exon Smith 
1049ef512b99SJustin Bogner   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
105038402dc9SDuncan P. N. Exon Smith   return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
105138402dc9SDuncan P. N. Exon Smith                                       scaleBranchWeight(FalseCount, Scale));
1052ef512b99SJustin Bogner }
1053ef512b99SJustin Bogner 
105495a27b0eSBob Wilson llvm::MDNode *CodeGenPGO::createBranchWeights(ArrayRef<uint64_t> Weights) {
105538402dc9SDuncan P. N. Exon Smith   // We need at least two elements to create meaningful weights.
105638402dc9SDuncan P. N. Exon Smith   if (Weights.size() < 2)
1057a5f804a7SDuncan P. N. Exon Smith     return nullptr;
105838402dc9SDuncan P. N. Exon Smith 
1059f3aefca7SJustin Bogner   // Check for empty weights.
1060f3aefca7SJustin Bogner   uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
1061f3aefca7SJustin Bogner   if (MaxWeight == 0)
1062f3aefca7SJustin Bogner     return nullptr;
1063f3aefca7SJustin Bogner 
106438402dc9SDuncan P. N. Exon Smith   // Calculate how to scale down to 32-bits.
1065f3aefca7SJustin Bogner   uint64_t Scale = calculateWeightScale(MaxWeight);
106638402dc9SDuncan P. N. Exon Smith 
1067ef512b99SJustin Bogner   SmallVector<uint32_t, 16> ScaledWeights;
1068ef512b99SJustin Bogner   ScaledWeights.reserve(Weights.size());
106938402dc9SDuncan P. N. Exon Smith   for (uint64_t W : Weights)
107038402dc9SDuncan P. N. Exon Smith     ScaledWeights.push_back(scaleBranchWeight(W, Scale));
107138402dc9SDuncan P. N. Exon Smith 
107238402dc9SDuncan P. N. Exon Smith   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
1073ef512b99SJustin Bogner   return MDHelper.createBranchWeights(ScaledWeights);
1074ef512b99SJustin Bogner }
1075bf854f0fSBob Wilson 
1076bf854f0fSBob Wilson llvm::MDNode *CodeGenPGO::createLoopWeights(const Stmt *Cond,
1077bf854f0fSBob Wilson                                             RegionCounter &Cnt) {
1078bf854f0fSBob Wilson   if (!haveRegionCounts())
1079a5f804a7SDuncan P. N. Exon Smith     return nullptr;
1080bf854f0fSBob Wilson   uint64_t LoopCount = Cnt.getCount();
1081bf854f0fSBob Wilson   uint64_t CondCount = 0;
1082bf854f0fSBob Wilson   bool Found = getStmtCount(Cond, CondCount);
1083bf854f0fSBob Wilson   assert(Found && "missing expected loop condition count");
1084bf854f0fSBob Wilson   (void)Found;
1085bf854f0fSBob Wilson   if (CondCount == 0)
1086a5f804a7SDuncan P. N. Exon Smith     return nullptr;
1087bf854f0fSBob Wilson   return createBranchWeights(LoopCount,
1088bf854f0fSBob Wilson                              std::max(CondCount, LoopCount) - LoopCount);
1089bf854f0fSBob Wilson }
1090