10b57cec5SDimitry Andric //===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Instrumentation-based profile-guided optimization
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "CodeGenPGO.h"
140b57cec5SDimitry Andric #include "CodeGenFunction.h"
150b57cec5SDimitry Andric #include "CoverageMappingGen.h"
160b57cec5SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
170b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h"
180b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
190b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h"
20480093f4SDimitry Andric #include "llvm/Support/CommandLine.h"
210b57cec5SDimitry Andric #include "llvm/Support/Endian.h"
220b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
230b57cec5SDimitry Andric #include "llvm/Support/MD5.h"
24bdd1243dSDimitry Andric #include <optional>
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric static llvm::cl::opt<bool>
2781ad6265SDimitry Andric     EnableValueProfiling("enable-value-profiling",
280b57cec5SDimitry Andric                          llvm::cl::desc("Enable value profiling"),
290b57cec5SDimitry Andric                          llvm::cl::Hidden, llvm::cl::init(false));
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric using namespace clang;
320b57cec5SDimitry Andric using namespace CodeGen;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric void CodeGenPGO::setFuncName(StringRef Name,
350b57cec5SDimitry Andric                              llvm::GlobalValue::LinkageTypes Linkage) {
360b57cec5SDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
370b57cec5SDimitry Andric   FuncName = llvm::getPGOFuncName(
380b57cec5SDimitry Andric       Name, Linkage, CGM.getCodeGenOpts().MainFileName,
390b57cec5SDimitry Andric       PGOReader ? PGOReader->getVersion() : llvm::IndexedInstrProf::Version);
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric   // If we're generating a profile, create a variable for the name.
420b57cec5SDimitry Andric   if (CGM.getCodeGenOpts().hasProfileClangInstr())
430b57cec5SDimitry Andric     FuncNameVar = llvm::createPGOFuncNameVar(CGM.getModule(), Linkage, FuncName);
440b57cec5SDimitry Andric }
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric void CodeGenPGO::setFuncName(llvm::Function *Fn) {
470b57cec5SDimitry Andric   setFuncName(Fn->getName(), Fn->getLinkage());
480b57cec5SDimitry Andric   // Create PGOFuncName meta data.
490b57cec5SDimitry Andric   llvm::createPGOFuncNameMetadata(*Fn, FuncName);
500b57cec5SDimitry Andric }
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric /// The version of the PGO hash algorithm.
530b57cec5SDimitry Andric enum PGOHashVersion : unsigned {
540b57cec5SDimitry Andric   PGO_HASH_V1,
550b57cec5SDimitry Andric   PGO_HASH_V2,
565ffd83dbSDimitry Andric   PGO_HASH_V3,
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   // Keep this set to the latest hash version.
595ffd83dbSDimitry Andric   PGO_HASH_LATEST = PGO_HASH_V3
600b57cec5SDimitry Andric };
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric namespace {
630b57cec5SDimitry Andric /// Stable hasher for PGO region counters.
640b57cec5SDimitry Andric ///
650b57cec5SDimitry Andric /// PGOHash produces a stable hash of a given function's control flow.
660b57cec5SDimitry Andric ///
670b57cec5SDimitry Andric /// Changing the output of this hash will invalidate all previously generated
680b57cec5SDimitry Andric /// profiles -- i.e., don't do it.
690b57cec5SDimitry Andric ///
700b57cec5SDimitry Andric /// \note  When this hash does eventually change (years?), we still need to
710b57cec5SDimitry Andric /// support old hashes.  We'll need to pull in the version number from the
720b57cec5SDimitry Andric /// profile data format and use the matching hash function.
730b57cec5SDimitry Andric class PGOHash {
740b57cec5SDimitry Andric   uint64_t Working;
750b57cec5SDimitry Andric   unsigned Count;
760b57cec5SDimitry Andric   PGOHashVersion HashVersion;
770b57cec5SDimitry Andric   llvm::MD5 MD5;
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   static const int NumBitsPerType = 6;
800b57cec5SDimitry Andric   static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
810b57cec5SDimitry Andric   static const unsigned TooBig = 1u << NumBitsPerType;
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric public:
840b57cec5SDimitry Andric   /// Hash values for AST nodes.
850b57cec5SDimitry Andric   ///
860b57cec5SDimitry Andric   /// Distinct values for AST nodes that have region counters attached.
870b57cec5SDimitry Andric   ///
880b57cec5SDimitry Andric   /// These values must be stable.  All new members must be added at the end,
890b57cec5SDimitry Andric   /// and no members should be removed.  Changing the enumeration value for an
900b57cec5SDimitry Andric   /// AST node will affect the hash of every function that contains that node.
910b57cec5SDimitry Andric   enum HashType : unsigned char {
920b57cec5SDimitry Andric     None = 0,
930b57cec5SDimitry Andric     LabelStmt = 1,
940b57cec5SDimitry Andric     WhileStmt,
950b57cec5SDimitry Andric     DoStmt,
960b57cec5SDimitry Andric     ForStmt,
970b57cec5SDimitry Andric     CXXForRangeStmt,
980b57cec5SDimitry Andric     ObjCForCollectionStmt,
990b57cec5SDimitry Andric     SwitchStmt,
1000b57cec5SDimitry Andric     CaseStmt,
1010b57cec5SDimitry Andric     DefaultStmt,
1020b57cec5SDimitry Andric     IfStmt,
1030b57cec5SDimitry Andric     CXXTryStmt,
1040b57cec5SDimitry Andric     CXXCatchStmt,
1050b57cec5SDimitry Andric     ConditionalOperator,
1060b57cec5SDimitry Andric     BinaryOperatorLAnd,
1070b57cec5SDimitry Andric     BinaryOperatorLOr,
1080b57cec5SDimitry Andric     BinaryConditionalOperator,
1090b57cec5SDimitry Andric     // The preceding values are available with PGO_HASH_V1.
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric     EndOfScope,
1120b57cec5SDimitry Andric     IfThenBranch,
1130b57cec5SDimitry Andric     IfElseBranch,
1140b57cec5SDimitry Andric     GotoStmt,
1150b57cec5SDimitry Andric     IndirectGotoStmt,
1160b57cec5SDimitry Andric     BreakStmt,
1170b57cec5SDimitry Andric     ContinueStmt,
1180b57cec5SDimitry Andric     ReturnStmt,
1190b57cec5SDimitry Andric     ThrowExpr,
1200b57cec5SDimitry Andric     UnaryOperatorLNot,
1210b57cec5SDimitry Andric     BinaryOperatorLT,
1220b57cec5SDimitry Andric     BinaryOperatorGT,
1230b57cec5SDimitry Andric     BinaryOperatorLE,
1240b57cec5SDimitry Andric     BinaryOperatorGE,
1250b57cec5SDimitry Andric     BinaryOperatorEQ,
1260b57cec5SDimitry Andric     BinaryOperatorNE,
1275ffd83dbSDimitry Andric     // The preceding values are available since PGO_HASH_V2.
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric     // Keep this last.  It's for the static assert that follows.
1300b57cec5SDimitry Andric     LastHashType
1310b57cec5SDimitry Andric   };
1320b57cec5SDimitry Andric   static_assert(LastHashType <= TooBig, "Too many types in HashType");
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric   PGOHash(PGOHashVersion HashVersion)
13504eeddc0SDimitry Andric       : Working(0), Count(0), HashVersion(HashVersion) {}
1360b57cec5SDimitry Andric   void combine(HashType Type);
1370b57cec5SDimitry Andric   uint64_t finalize();
1380b57cec5SDimitry Andric   PGOHashVersion getHashVersion() const { return HashVersion; }
1390b57cec5SDimitry Andric };
1400b57cec5SDimitry Andric const int PGOHash::NumBitsPerType;
1410b57cec5SDimitry Andric const unsigned PGOHash::NumTypesPerWord;
1420b57cec5SDimitry Andric const unsigned PGOHash::TooBig;
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric /// Get the PGO hash version used in the given indexed profile.
1450b57cec5SDimitry Andric static PGOHashVersion getPGOHashVersion(llvm::IndexedInstrProfReader *PGOReader,
1460b57cec5SDimitry Andric                                         CodeGenModule &CGM) {
1470b57cec5SDimitry Andric   if (PGOReader->getVersion() <= 4)
1480b57cec5SDimitry Andric     return PGO_HASH_V1;
1495ffd83dbSDimitry Andric   if (PGOReader->getVersion() <= 5)
1500b57cec5SDimitry Andric     return PGO_HASH_V2;
1515ffd83dbSDimitry Andric   return PGO_HASH_V3;
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
1550b57cec5SDimitry Andric struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
1560b57cec5SDimitry Andric   using Base = RecursiveASTVisitor<MapRegionCounters>;
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric   /// The next counter value to assign.
1590b57cec5SDimitry Andric   unsigned NextCounter;
1600b57cec5SDimitry Andric   /// The function hash.
1610b57cec5SDimitry Andric   PGOHash Hash;
1620b57cec5SDimitry Andric   /// The map of statements to counters.
1630b57cec5SDimitry Andric   llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
164e8d8bef9SDimitry Andric   /// The profile version.
165e8d8bef9SDimitry Andric   uint64_t ProfileVersion;
1660b57cec5SDimitry Andric 
167e8d8bef9SDimitry Andric   MapRegionCounters(PGOHashVersion HashVersion, uint64_t ProfileVersion,
1680b57cec5SDimitry Andric                     llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
169e8d8bef9SDimitry Andric       : NextCounter(0), Hash(HashVersion), CounterMap(CounterMap),
170e8d8bef9SDimitry Andric         ProfileVersion(ProfileVersion) {}
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric   // Blocks and lambdas are handled as separate functions, so we need not
1730b57cec5SDimitry Andric   // traverse them in the parent context.
1740b57cec5SDimitry Andric   bool TraverseBlockExpr(BlockExpr *BE) { return true; }
1750b57cec5SDimitry Andric   bool TraverseLambdaExpr(LambdaExpr *LE) {
1760b57cec5SDimitry Andric     // Traverse the captures, but not the body.
177480093f4SDimitry Andric     for (auto C : zip(LE->captures(), LE->capture_inits()))
1780b57cec5SDimitry Andric       TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
1790b57cec5SDimitry Andric     return true;
1800b57cec5SDimitry Andric   }
1810b57cec5SDimitry Andric   bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric   bool VisitDecl(const Decl *D) {
1840b57cec5SDimitry Andric     switch (D->getKind()) {
1850b57cec5SDimitry Andric     default:
1860b57cec5SDimitry Andric       break;
1870b57cec5SDimitry Andric     case Decl::Function:
1880b57cec5SDimitry Andric     case Decl::CXXMethod:
1890b57cec5SDimitry Andric     case Decl::CXXConstructor:
1900b57cec5SDimitry Andric     case Decl::CXXDestructor:
1910b57cec5SDimitry Andric     case Decl::CXXConversion:
1920b57cec5SDimitry Andric     case Decl::ObjCMethod:
1930b57cec5SDimitry Andric     case Decl::Block:
1940b57cec5SDimitry Andric     case Decl::Captured:
1950b57cec5SDimitry Andric       CounterMap[D->getBody()] = NextCounter++;
1960b57cec5SDimitry Andric       break;
1970b57cec5SDimitry Andric     }
1980b57cec5SDimitry Andric     return true;
1990b57cec5SDimitry Andric   }
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   /// If \p S gets a fresh counter, update the counter mappings. Return the
2020b57cec5SDimitry Andric   /// V1 hash of \p S.
2030b57cec5SDimitry Andric   PGOHash::HashType updateCounterMappings(Stmt *S) {
2040b57cec5SDimitry Andric     auto Type = getHashType(PGO_HASH_V1, S);
2050b57cec5SDimitry Andric     if (Type != PGOHash::None)
2060b57cec5SDimitry Andric       CounterMap[S] = NextCounter++;
2070b57cec5SDimitry Andric     return Type;
2080b57cec5SDimitry Andric   }
2090b57cec5SDimitry Andric 
210e8d8bef9SDimitry Andric   /// The RHS of all logical operators gets a fresh counter in order to count
211e8d8bef9SDimitry Andric   /// how many times the RHS evaluates to true or false, depending on the
212e8d8bef9SDimitry Andric   /// semantics of the operator. This is only valid for ">= v7" of the profile
213e8d8bef9SDimitry Andric   /// version so that we facilitate backward compatibility.
214e8d8bef9SDimitry Andric   bool VisitBinaryOperator(BinaryOperator *S) {
215e8d8bef9SDimitry Andric     if (ProfileVersion >= llvm::IndexedInstrProf::Version7)
216e8d8bef9SDimitry Andric       if (S->isLogicalOp() &&
217e8d8bef9SDimitry Andric           CodeGenFunction::isInstrumentedCondition(S->getRHS()))
218e8d8bef9SDimitry Andric         CounterMap[S->getRHS()] = NextCounter++;
219e8d8bef9SDimitry Andric     return Base::VisitBinaryOperator(S);
220e8d8bef9SDimitry Andric   }
221e8d8bef9SDimitry Andric 
2220b57cec5SDimitry Andric   /// Include \p S in the function hash.
2230b57cec5SDimitry Andric   bool VisitStmt(Stmt *S) {
2240b57cec5SDimitry Andric     auto Type = updateCounterMappings(S);
2250b57cec5SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
2260b57cec5SDimitry Andric       Type = getHashType(Hash.getHashVersion(), S);
2270b57cec5SDimitry Andric     if (Type != PGOHash::None)
2280b57cec5SDimitry Andric       Hash.combine(Type);
2290b57cec5SDimitry Andric     return true;
2300b57cec5SDimitry Andric   }
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric   bool TraverseIfStmt(IfStmt *If) {
2330b57cec5SDimitry Andric     // If we used the V1 hash, use the default traversal.
2340b57cec5SDimitry Andric     if (Hash.getHashVersion() == PGO_HASH_V1)
2350b57cec5SDimitry Andric       return Base::TraverseIfStmt(If);
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric     // Otherwise, keep track of which branch we're in while traversing.
2380b57cec5SDimitry Andric     VisitStmt(If);
2390b57cec5SDimitry Andric     for (Stmt *CS : If->children()) {
2400b57cec5SDimitry Andric       if (!CS)
2410b57cec5SDimitry Andric         continue;
2420b57cec5SDimitry Andric       if (CS == If->getThen())
2430b57cec5SDimitry Andric         Hash.combine(PGOHash::IfThenBranch);
2440b57cec5SDimitry Andric       else if (CS == If->getElse())
2450b57cec5SDimitry Andric         Hash.combine(PGOHash::IfElseBranch);
2460b57cec5SDimitry Andric       TraverseStmt(CS);
2470b57cec5SDimitry Andric     }
2480b57cec5SDimitry Andric     Hash.combine(PGOHash::EndOfScope);
2490b57cec5SDimitry Andric     return true;
2500b57cec5SDimitry Andric   }
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric // If the statement type \p N is nestable, and its nesting impacts profile
2530b57cec5SDimitry Andric // stability, define a custom traversal which tracks the end of the statement
2540b57cec5SDimitry Andric // in the hash (provided we're not using the V1 hash).
2550b57cec5SDimitry Andric #define DEFINE_NESTABLE_TRAVERSAL(N)                                           \
2560b57cec5SDimitry Andric   bool Traverse##N(N *S) {                                                     \
2570b57cec5SDimitry Andric     Base::Traverse##N(S);                                                      \
2580b57cec5SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)                                  \
2590b57cec5SDimitry Andric       Hash.combine(PGOHash::EndOfScope);                                       \
2600b57cec5SDimitry Andric     return true;                                                               \
2610b57cec5SDimitry Andric   }
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(WhileStmt)
2640b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(DoStmt)
2650b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(ForStmt)
2660b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXForRangeStmt)
2670b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(ObjCForCollectionStmt)
2680b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXTryStmt)
2690b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXCatchStmt)
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric   /// Get version \p HashVersion of the PGO hash for \p S.
2720b57cec5SDimitry Andric   PGOHash::HashType getHashType(PGOHashVersion HashVersion, const Stmt *S) {
2730b57cec5SDimitry Andric     switch (S->getStmtClass()) {
2740b57cec5SDimitry Andric     default:
2750b57cec5SDimitry Andric       break;
2760b57cec5SDimitry Andric     case Stmt::LabelStmtClass:
2770b57cec5SDimitry Andric       return PGOHash::LabelStmt;
2780b57cec5SDimitry Andric     case Stmt::WhileStmtClass:
2790b57cec5SDimitry Andric       return PGOHash::WhileStmt;
2800b57cec5SDimitry Andric     case Stmt::DoStmtClass:
2810b57cec5SDimitry Andric       return PGOHash::DoStmt;
2820b57cec5SDimitry Andric     case Stmt::ForStmtClass:
2830b57cec5SDimitry Andric       return PGOHash::ForStmt;
2840b57cec5SDimitry Andric     case Stmt::CXXForRangeStmtClass:
2850b57cec5SDimitry Andric       return PGOHash::CXXForRangeStmt;
2860b57cec5SDimitry Andric     case Stmt::ObjCForCollectionStmtClass:
2870b57cec5SDimitry Andric       return PGOHash::ObjCForCollectionStmt;
2880b57cec5SDimitry Andric     case Stmt::SwitchStmtClass:
2890b57cec5SDimitry Andric       return PGOHash::SwitchStmt;
2900b57cec5SDimitry Andric     case Stmt::CaseStmtClass:
2910b57cec5SDimitry Andric       return PGOHash::CaseStmt;
2920b57cec5SDimitry Andric     case Stmt::DefaultStmtClass:
2930b57cec5SDimitry Andric       return PGOHash::DefaultStmt;
2940b57cec5SDimitry Andric     case Stmt::IfStmtClass:
2950b57cec5SDimitry Andric       return PGOHash::IfStmt;
2960b57cec5SDimitry Andric     case Stmt::CXXTryStmtClass:
2970b57cec5SDimitry Andric       return PGOHash::CXXTryStmt;
2980b57cec5SDimitry Andric     case Stmt::CXXCatchStmtClass:
2990b57cec5SDimitry Andric       return PGOHash::CXXCatchStmt;
3000b57cec5SDimitry Andric     case Stmt::ConditionalOperatorClass:
3010b57cec5SDimitry Andric       return PGOHash::ConditionalOperator;
3020b57cec5SDimitry Andric     case Stmt::BinaryConditionalOperatorClass:
3030b57cec5SDimitry Andric       return PGOHash::BinaryConditionalOperator;
3040b57cec5SDimitry Andric     case Stmt::BinaryOperatorClass: {
3050b57cec5SDimitry Andric       const BinaryOperator *BO = cast<BinaryOperator>(S);
3060b57cec5SDimitry Andric       if (BO->getOpcode() == BO_LAnd)
3070b57cec5SDimitry Andric         return PGOHash::BinaryOperatorLAnd;
3080b57cec5SDimitry Andric       if (BO->getOpcode() == BO_LOr)
3090b57cec5SDimitry Andric         return PGOHash::BinaryOperatorLOr;
3105ffd83dbSDimitry Andric       if (HashVersion >= PGO_HASH_V2) {
3110b57cec5SDimitry Andric         switch (BO->getOpcode()) {
3120b57cec5SDimitry Andric         default:
3130b57cec5SDimitry Andric           break;
3140b57cec5SDimitry Andric         case BO_LT:
3150b57cec5SDimitry Andric           return PGOHash::BinaryOperatorLT;
3160b57cec5SDimitry Andric         case BO_GT:
3170b57cec5SDimitry Andric           return PGOHash::BinaryOperatorGT;
3180b57cec5SDimitry Andric         case BO_LE:
3190b57cec5SDimitry Andric           return PGOHash::BinaryOperatorLE;
3200b57cec5SDimitry Andric         case BO_GE:
3210b57cec5SDimitry Andric           return PGOHash::BinaryOperatorGE;
3220b57cec5SDimitry Andric         case BO_EQ:
3230b57cec5SDimitry Andric           return PGOHash::BinaryOperatorEQ;
3240b57cec5SDimitry Andric         case BO_NE:
3250b57cec5SDimitry Andric           return PGOHash::BinaryOperatorNE;
3260b57cec5SDimitry Andric         }
3270b57cec5SDimitry Andric       }
3280b57cec5SDimitry Andric       break;
3290b57cec5SDimitry Andric     }
3300b57cec5SDimitry Andric     }
3310b57cec5SDimitry Andric 
3325ffd83dbSDimitry Andric     if (HashVersion >= PGO_HASH_V2) {
3330b57cec5SDimitry Andric       switch (S->getStmtClass()) {
3340b57cec5SDimitry Andric       default:
3350b57cec5SDimitry Andric         break;
3360b57cec5SDimitry Andric       case Stmt::GotoStmtClass:
3370b57cec5SDimitry Andric         return PGOHash::GotoStmt;
3380b57cec5SDimitry Andric       case Stmt::IndirectGotoStmtClass:
3390b57cec5SDimitry Andric         return PGOHash::IndirectGotoStmt;
3400b57cec5SDimitry Andric       case Stmt::BreakStmtClass:
3410b57cec5SDimitry Andric         return PGOHash::BreakStmt;
3420b57cec5SDimitry Andric       case Stmt::ContinueStmtClass:
3430b57cec5SDimitry Andric         return PGOHash::ContinueStmt;
3440b57cec5SDimitry Andric       case Stmt::ReturnStmtClass:
3450b57cec5SDimitry Andric         return PGOHash::ReturnStmt;
3460b57cec5SDimitry Andric       case Stmt::CXXThrowExprClass:
3470b57cec5SDimitry Andric         return PGOHash::ThrowExpr;
3480b57cec5SDimitry Andric       case Stmt::UnaryOperatorClass: {
3490b57cec5SDimitry Andric         const UnaryOperator *UO = cast<UnaryOperator>(S);
3500b57cec5SDimitry Andric         if (UO->getOpcode() == UO_LNot)
3510b57cec5SDimitry Andric           return PGOHash::UnaryOperatorLNot;
3520b57cec5SDimitry Andric         break;
3530b57cec5SDimitry Andric       }
3540b57cec5SDimitry Andric       }
3550b57cec5SDimitry Andric     }
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric     return PGOHash::None;
3580b57cec5SDimitry Andric   }
3590b57cec5SDimitry Andric };
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric /// A StmtVisitor that propagates the raw counts through the AST and
3620b57cec5SDimitry Andric /// records the count at statements where the value may change.
3630b57cec5SDimitry Andric struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
3640b57cec5SDimitry Andric   /// PGO state.
3650b57cec5SDimitry Andric   CodeGenPGO &PGO;
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric   /// A flag that is set when the current count should be recorded on the
3680b57cec5SDimitry Andric   /// next statement, such as at the exit of a loop.
3690b57cec5SDimitry Andric   bool RecordNextStmtCount;
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric   /// The count at the current location in the traversal.
3720b57cec5SDimitry Andric   uint64_t CurrentCount;
3730b57cec5SDimitry Andric 
3740b57cec5SDimitry Andric   /// The map of statements to count values.
3750b57cec5SDimitry Andric   llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric   /// BreakContinueStack - Keep counts of breaks and continues inside loops.
3780b57cec5SDimitry Andric   struct BreakContinue {
379*c9157d92SDimitry Andric     uint64_t BreakCount = 0;
380*c9157d92SDimitry Andric     uint64_t ContinueCount = 0;
381*c9157d92SDimitry Andric     BreakContinue() = default;
3820b57cec5SDimitry Andric   };
3830b57cec5SDimitry Andric   SmallVector<BreakContinue, 8> BreakContinueStack;
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric   ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
3860b57cec5SDimitry Andric                       CodeGenPGO &PGO)
3870b57cec5SDimitry Andric       : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric   void RecordStmtCount(const Stmt *S) {
3900b57cec5SDimitry Andric     if (RecordNextStmtCount) {
3910b57cec5SDimitry Andric       CountMap[S] = CurrentCount;
3920b57cec5SDimitry Andric       RecordNextStmtCount = false;
3930b57cec5SDimitry Andric     }
3940b57cec5SDimitry Andric   }
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric   /// Set and return the current count.
3970b57cec5SDimitry Andric   uint64_t setCount(uint64_t Count) {
3980b57cec5SDimitry Andric     CurrentCount = Count;
3990b57cec5SDimitry Andric     return Count;
4000b57cec5SDimitry Andric   }
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric   void VisitStmt(const Stmt *S) {
4030b57cec5SDimitry Andric     RecordStmtCount(S);
4040b57cec5SDimitry Andric     for (const Stmt *Child : S->children())
4050b57cec5SDimitry Andric       if (Child)
4060b57cec5SDimitry Andric         this->Visit(Child);
4070b57cec5SDimitry Andric   }
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric   void VisitFunctionDecl(const FunctionDecl *D) {
4100b57cec5SDimitry Andric     // Counter tracks entry to the function body.
4110b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
4120b57cec5SDimitry Andric     CountMap[D->getBody()] = BodyCount;
4130b57cec5SDimitry Andric     Visit(D->getBody());
4140b57cec5SDimitry Andric   }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   // Skip lambda expressions. We visit these as FunctionDecls when we're
4170b57cec5SDimitry Andric   // generating them and aren't interested in the body when generating a
4180b57cec5SDimitry Andric   // parent context.
4190b57cec5SDimitry Andric   void VisitLambdaExpr(const LambdaExpr *LE) {}
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric   void VisitCapturedDecl(const CapturedDecl *D) {
4220b57cec5SDimitry Andric     // Counter tracks entry to the capture body.
4230b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
4240b57cec5SDimitry Andric     CountMap[D->getBody()] = BodyCount;
4250b57cec5SDimitry Andric     Visit(D->getBody());
4260b57cec5SDimitry Andric   }
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric   void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
4290b57cec5SDimitry Andric     // Counter tracks entry to the method body.
4300b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
4310b57cec5SDimitry Andric     CountMap[D->getBody()] = BodyCount;
4320b57cec5SDimitry Andric     Visit(D->getBody());
4330b57cec5SDimitry Andric   }
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   void VisitBlockDecl(const BlockDecl *D) {
4360b57cec5SDimitry Andric     // Counter tracks entry to the block body.
4370b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
4380b57cec5SDimitry Andric     CountMap[D->getBody()] = BodyCount;
4390b57cec5SDimitry Andric     Visit(D->getBody());
4400b57cec5SDimitry Andric   }
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   void VisitReturnStmt(const ReturnStmt *S) {
4430b57cec5SDimitry Andric     RecordStmtCount(S);
4440b57cec5SDimitry Andric     if (S->getRetValue())
4450b57cec5SDimitry Andric       Visit(S->getRetValue());
4460b57cec5SDimitry Andric     CurrentCount = 0;
4470b57cec5SDimitry Andric     RecordNextStmtCount = true;
4480b57cec5SDimitry Andric   }
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric   void VisitCXXThrowExpr(const CXXThrowExpr *E) {
4510b57cec5SDimitry Andric     RecordStmtCount(E);
4520b57cec5SDimitry Andric     if (E->getSubExpr())
4530b57cec5SDimitry Andric       Visit(E->getSubExpr());
4540b57cec5SDimitry Andric     CurrentCount = 0;
4550b57cec5SDimitry Andric     RecordNextStmtCount = true;
4560b57cec5SDimitry Andric   }
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric   void VisitGotoStmt(const GotoStmt *S) {
4590b57cec5SDimitry Andric     RecordStmtCount(S);
4600b57cec5SDimitry Andric     CurrentCount = 0;
4610b57cec5SDimitry Andric     RecordNextStmtCount = true;
4620b57cec5SDimitry Andric   }
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric   void VisitLabelStmt(const LabelStmt *S) {
4650b57cec5SDimitry Andric     RecordNextStmtCount = false;
4660b57cec5SDimitry Andric     // Counter tracks the block following the label.
4670b57cec5SDimitry Andric     uint64_t BlockCount = setCount(PGO.getRegionCount(S));
4680b57cec5SDimitry Andric     CountMap[S] = BlockCount;
4690b57cec5SDimitry Andric     Visit(S->getSubStmt());
4700b57cec5SDimitry Andric   }
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric   void VisitBreakStmt(const BreakStmt *S) {
4730b57cec5SDimitry Andric     RecordStmtCount(S);
4740b57cec5SDimitry Andric     assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
4750b57cec5SDimitry Andric     BreakContinueStack.back().BreakCount += CurrentCount;
4760b57cec5SDimitry Andric     CurrentCount = 0;
4770b57cec5SDimitry Andric     RecordNextStmtCount = true;
4780b57cec5SDimitry Andric   }
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric   void VisitContinueStmt(const ContinueStmt *S) {
4810b57cec5SDimitry Andric     RecordStmtCount(S);
4820b57cec5SDimitry Andric     assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
4830b57cec5SDimitry Andric     BreakContinueStack.back().ContinueCount += CurrentCount;
4840b57cec5SDimitry Andric     CurrentCount = 0;
4850b57cec5SDimitry Andric     RecordNextStmtCount = true;
4860b57cec5SDimitry Andric   }
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric   void VisitWhileStmt(const WhileStmt *S) {
4890b57cec5SDimitry Andric     RecordStmtCount(S);
4900b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
4930b57cec5SDimitry Andric     // Visit the body region first so the break/continue adjustments can be
4940b57cec5SDimitry Andric     // included when visiting the condition.
4950b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
4960b57cec5SDimitry Andric     CountMap[S->getBody()] = CurrentCount;
4970b57cec5SDimitry Andric     Visit(S->getBody());
4980b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric     // ...then go back and propagate counts through the condition. The count
5010b57cec5SDimitry Andric     // at the start of the condition is the sum of the incoming edges,
5020b57cec5SDimitry Andric     // the backedge from the end of the loop body, and the edges from
5030b57cec5SDimitry Andric     // continue statements.
5040b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
5050b57cec5SDimitry Andric     uint64_t CondCount =
5060b57cec5SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
5070b57cec5SDimitry Andric     CountMap[S->getCond()] = CondCount;
5080b57cec5SDimitry Andric     Visit(S->getCond());
5090b57cec5SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
5100b57cec5SDimitry Andric     RecordNextStmtCount = true;
5110b57cec5SDimitry Andric   }
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric   void VisitDoStmt(const DoStmt *S) {
5140b57cec5SDimitry Andric     RecordStmtCount(S);
5150b57cec5SDimitry Andric     uint64_t LoopCount = PGO.getRegionCount(S);
5160b57cec5SDimitry Andric 
5170b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
5180b57cec5SDimitry Andric     // The count doesn't include the fallthrough from the parent scope. Add it.
5190b57cec5SDimitry Andric     uint64_t BodyCount = setCount(LoopCount + CurrentCount);
5200b57cec5SDimitry Andric     CountMap[S->getBody()] = BodyCount;
5210b57cec5SDimitry Andric     Visit(S->getBody());
5220b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
5230b57cec5SDimitry Andric 
5240b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
5250b57cec5SDimitry Andric     // The count at the start of the condition is equal to the count at the
5260b57cec5SDimitry Andric     // end of the body, plus any continues.
5270b57cec5SDimitry Andric     uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount);
5280b57cec5SDimitry Andric     CountMap[S->getCond()] = CondCount;
5290b57cec5SDimitry Andric     Visit(S->getCond());
5300b57cec5SDimitry Andric     setCount(BC.BreakCount + CondCount - LoopCount);
5310b57cec5SDimitry Andric     RecordNextStmtCount = true;
5320b57cec5SDimitry Andric   }
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric   void VisitForStmt(const ForStmt *S) {
5350b57cec5SDimitry Andric     RecordStmtCount(S);
5360b57cec5SDimitry Andric     if (S->getInit())
5370b57cec5SDimitry Andric       Visit(S->getInit());
5380b57cec5SDimitry Andric 
5390b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
5400b57cec5SDimitry Andric 
5410b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
5420b57cec5SDimitry Andric     // Visit the body region first. (This is basically the same as a while
5430b57cec5SDimitry Andric     // loop; see further comments in VisitWhileStmt.)
5440b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
5450b57cec5SDimitry Andric     CountMap[S->getBody()] = BodyCount;
5460b57cec5SDimitry Andric     Visit(S->getBody());
5470b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
5480b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric     // The increment is essentially part of the body but it needs to include
5510b57cec5SDimitry Andric     // the count for all the continue statements.
5520b57cec5SDimitry Andric     if (S->getInc()) {
5530b57cec5SDimitry Andric       uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
5540b57cec5SDimitry Andric       CountMap[S->getInc()] = IncCount;
5550b57cec5SDimitry Andric       Visit(S->getInc());
5560b57cec5SDimitry Andric     }
5570b57cec5SDimitry Andric 
5580b57cec5SDimitry Andric     // ...then go back and propagate counts through the condition.
5590b57cec5SDimitry Andric     uint64_t CondCount =
5600b57cec5SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
5610b57cec5SDimitry Andric     if (S->getCond()) {
5620b57cec5SDimitry Andric       CountMap[S->getCond()] = CondCount;
5630b57cec5SDimitry Andric       Visit(S->getCond());
5640b57cec5SDimitry Andric     }
5650b57cec5SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
5660b57cec5SDimitry Andric     RecordNextStmtCount = true;
5670b57cec5SDimitry Andric   }
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric   void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
5700b57cec5SDimitry Andric     RecordStmtCount(S);
5710b57cec5SDimitry Andric     if (S->getInit())
5720b57cec5SDimitry Andric       Visit(S->getInit());
5730b57cec5SDimitry Andric     Visit(S->getLoopVarStmt());
5740b57cec5SDimitry Andric     Visit(S->getRangeStmt());
5750b57cec5SDimitry Andric     Visit(S->getBeginStmt());
5760b57cec5SDimitry Andric     Visit(S->getEndStmt());
5770b57cec5SDimitry Andric 
5780b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
5790b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
5800b57cec5SDimitry Andric     // Visit the body region first. (This is basically the same as a while
5810b57cec5SDimitry Andric     // loop; see further comments in VisitWhileStmt.)
5820b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
5830b57cec5SDimitry Andric     CountMap[S->getBody()] = BodyCount;
5840b57cec5SDimitry Andric     Visit(S->getBody());
5850b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
5860b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric     // The increment is essentially part of the body but it needs to include
5890b57cec5SDimitry Andric     // the count for all the continue statements.
5900b57cec5SDimitry Andric     uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
5910b57cec5SDimitry Andric     CountMap[S->getInc()] = IncCount;
5920b57cec5SDimitry Andric     Visit(S->getInc());
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric     // ...then go back and propagate counts through the condition.
5950b57cec5SDimitry Andric     uint64_t CondCount =
5960b57cec5SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
5970b57cec5SDimitry Andric     CountMap[S->getCond()] = CondCount;
5980b57cec5SDimitry Andric     Visit(S->getCond());
5990b57cec5SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
6000b57cec5SDimitry Andric     RecordNextStmtCount = true;
6010b57cec5SDimitry Andric   }
6020b57cec5SDimitry Andric 
6030b57cec5SDimitry Andric   void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
6040b57cec5SDimitry Andric     RecordStmtCount(S);
6050b57cec5SDimitry Andric     Visit(S->getElement());
6060b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
6070b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
6080b57cec5SDimitry Andric     // Counter tracks the body of the loop.
6090b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
6100b57cec5SDimitry Andric     CountMap[S->getBody()] = BodyCount;
6110b57cec5SDimitry Andric     Visit(S->getBody());
6120b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
6130b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
6140b57cec5SDimitry Andric 
6150b57cec5SDimitry Andric     setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount -
6160b57cec5SDimitry Andric              BodyCount);
6170b57cec5SDimitry Andric     RecordNextStmtCount = true;
6180b57cec5SDimitry Andric   }
6190b57cec5SDimitry Andric 
6200b57cec5SDimitry Andric   void VisitSwitchStmt(const SwitchStmt *S) {
6210b57cec5SDimitry Andric     RecordStmtCount(S);
6220b57cec5SDimitry Andric     if (S->getInit())
6230b57cec5SDimitry Andric       Visit(S->getInit());
6240b57cec5SDimitry Andric     Visit(S->getCond());
6250b57cec5SDimitry Andric     CurrentCount = 0;
6260b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
6270b57cec5SDimitry Andric     Visit(S->getBody());
6280b57cec5SDimitry Andric     // If the switch is inside a loop, add the continue counts.
6290b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
6300b57cec5SDimitry Andric     if (!BreakContinueStack.empty())
6310b57cec5SDimitry Andric       BreakContinueStack.back().ContinueCount += BC.ContinueCount;
6320b57cec5SDimitry Andric     // Counter tracks the exit block of the switch.
6330b57cec5SDimitry Andric     setCount(PGO.getRegionCount(S));
6340b57cec5SDimitry Andric     RecordNextStmtCount = true;
6350b57cec5SDimitry Andric   }
6360b57cec5SDimitry Andric 
6370b57cec5SDimitry Andric   void VisitSwitchCase(const SwitchCase *S) {
6380b57cec5SDimitry Andric     RecordNextStmtCount = false;
6390b57cec5SDimitry Andric     // Counter for this particular case. This counts only jumps from the
6400b57cec5SDimitry Andric     // switch header and does not include fallthrough from the case before
6410b57cec5SDimitry Andric     // this one.
6420b57cec5SDimitry Andric     uint64_t CaseCount = PGO.getRegionCount(S);
6430b57cec5SDimitry Andric     setCount(CurrentCount + CaseCount);
6440b57cec5SDimitry Andric     // We need the count without fallthrough in the mapping, so it's more useful
6450b57cec5SDimitry Andric     // for branch probabilities.
6460b57cec5SDimitry Andric     CountMap[S] = CaseCount;
6470b57cec5SDimitry Andric     RecordNextStmtCount = true;
6480b57cec5SDimitry Andric     Visit(S->getSubStmt());
6490b57cec5SDimitry Andric   }
6500b57cec5SDimitry Andric 
6510b57cec5SDimitry Andric   void VisitIfStmt(const IfStmt *S) {
6520b57cec5SDimitry Andric     RecordStmtCount(S);
653349cc55cSDimitry Andric 
654349cc55cSDimitry Andric     if (S->isConsteval()) {
655349cc55cSDimitry Andric       const Stmt *Stm = S->isNegatedConsteval() ? S->getThen() : S->getElse();
656349cc55cSDimitry Andric       if (Stm)
657349cc55cSDimitry Andric         Visit(Stm);
658349cc55cSDimitry Andric       return;
659349cc55cSDimitry Andric     }
660349cc55cSDimitry Andric 
6610b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
6620b57cec5SDimitry Andric     if (S->getInit())
6630b57cec5SDimitry Andric       Visit(S->getInit());
6640b57cec5SDimitry Andric     Visit(S->getCond());
6650b57cec5SDimitry Andric 
6660b57cec5SDimitry Andric     // Counter tracks the "then" part of an if statement. The count for
6670b57cec5SDimitry Andric     // the "else" part, if it exists, will be calculated from this counter.
6680b57cec5SDimitry Andric     uint64_t ThenCount = setCount(PGO.getRegionCount(S));
6690b57cec5SDimitry Andric     CountMap[S->getThen()] = ThenCount;
6700b57cec5SDimitry Andric     Visit(S->getThen());
6710b57cec5SDimitry Andric     uint64_t OutCount = CurrentCount;
6720b57cec5SDimitry Andric 
6730b57cec5SDimitry Andric     uint64_t ElseCount = ParentCount - ThenCount;
6740b57cec5SDimitry Andric     if (S->getElse()) {
6750b57cec5SDimitry Andric       setCount(ElseCount);
6760b57cec5SDimitry Andric       CountMap[S->getElse()] = ElseCount;
6770b57cec5SDimitry Andric       Visit(S->getElse());
6780b57cec5SDimitry Andric       OutCount += CurrentCount;
6790b57cec5SDimitry Andric     } else
6800b57cec5SDimitry Andric       OutCount += ElseCount;
6810b57cec5SDimitry Andric     setCount(OutCount);
6820b57cec5SDimitry Andric     RecordNextStmtCount = true;
6830b57cec5SDimitry Andric   }
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric   void VisitCXXTryStmt(const CXXTryStmt *S) {
6860b57cec5SDimitry Andric     RecordStmtCount(S);
6870b57cec5SDimitry Andric     Visit(S->getTryBlock());
6880b57cec5SDimitry Andric     for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
6890b57cec5SDimitry Andric       Visit(S->getHandler(I));
6900b57cec5SDimitry Andric     // Counter tracks the continuation block of the try statement.
6910b57cec5SDimitry Andric     setCount(PGO.getRegionCount(S));
6920b57cec5SDimitry Andric     RecordNextStmtCount = true;
6930b57cec5SDimitry Andric   }
6940b57cec5SDimitry Andric 
6950b57cec5SDimitry Andric   void VisitCXXCatchStmt(const CXXCatchStmt *S) {
6960b57cec5SDimitry Andric     RecordNextStmtCount = false;
6970b57cec5SDimitry Andric     // Counter tracks the catch statement's handler block.
6980b57cec5SDimitry Andric     uint64_t CatchCount = setCount(PGO.getRegionCount(S));
6990b57cec5SDimitry Andric     CountMap[S] = CatchCount;
7000b57cec5SDimitry Andric     Visit(S->getHandlerBlock());
7010b57cec5SDimitry Andric   }
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric   void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
7040b57cec5SDimitry Andric     RecordStmtCount(E);
7050b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
7060b57cec5SDimitry Andric     Visit(E->getCond());
7070b57cec5SDimitry Andric 
7080b57cec5SDimitry Andric     // Counter tracks the "true" part of a conditional operator. The
7090b57cec5SDimitry Andric     // count in the "false" part will be calculated from this counter.
7100b57cec5SDimitry Andric     uint64_t TrueCount = setCount(PGO.getRegionCount(E));
7110b57cec5SDimitry Andric     CountMap[E->getTrueExpr()] = TrueCount;
7120b57cec5SDimitry Andric     Visit(E->getTrueExpr());
7130b57cec5SDimitry Andric     uint64_t OutCount = CurrentCount;
7140b57cec5SDimitry Andric 
7150b57cec5SDimitry Andric     uint64_t FalseCount = setCount(ParentCount - TrueCount);
7160b57cec5SDimitry Andric     CountMap[E->getFalseExpr()] = FalseCount;
7170b57cec5SDimitry Andric     Visit(E->getFalseExpr());
7180b57cec5SDimitry Andric     OutCount += CurrentCount;
7190b57cec5SDimitry Andric 
7200b57cec5SDimitry Andric     setCount(OutCount);
7210b57cec5SDimitry Andric     RecordNextStmtCount = true;
7220b57cec5SDimitry Andric   }
7230b57cec5SDimitry Andric 
7240b57cec5SDimitry Andric   void VisitBinLAnd(const BinaryOperator *E) {
7250b57cec5SDimitry Andric     RecordStmtCount(E);
7260b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
7270b57cec5SDimitry Andric     Visit(E->getLHS());
7280b57cec5SDimitry Andric     // Counter tracks the right hand side of a logical and operator.
7290b57cec5SDimitry Andric     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
7300b57cec5SDimitry Andric     CountMap[E->getRHS()] = RHSCount;
7310b57cec5SDimitry Andric     Visit(E->getRHS());
7320b57cec5SDimitry Andric     setCount(ParentCount + RHSCount - CurrentCount);
7330b57cec5SDimitry Andric     RecordNextStmtCount = true;
7340b57cec5SDimitry Andric   }
7350b57cec5SDimitry Andric 
7360b57cec5SDimitry Andric   void VisitBinLOr(const BinaryOperator *E) {
7370b57cec5SDimitry Andric     RecordStmtCount(E);
7380b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
7390b57cec5SDimitry Andric     Visit(E->getLHS());
7400b57cec5SDimitry Andric     // Counter tracks the right hand side of a logical or operator.
7410b57cec5SDimitry Andric     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
7420b57cec5SDimitry Andric     CountMap[E->getRHS()] = RHSCount;
7430b57cec5SDimitry Andric     Visit(E->getRHS());
7440b57cec5SDimitry Andric     setCount(ParentCount + RHSCount - CurrentCount);
7450b57cec5SDimitry Andric     RecordNextStmtCount = true;
7460b57cec5SDimitry Andric   }
7470b57cec5SDimitry Andric };
7480b57cec5SDimitry Andric } // end anonymous namespace
7490b57cec5SDimitry Andric 
7500b57cec5SDimitry Andric void PGOHash::combine(HashType Type) {
7510b57cec5SDimitry Andric   // Check that we never combine 0 and only have six bits.
7520b57cec5SDimitry Andric   assert(Type && "Hash is invalid: unexpected type 0");
7530b57cec5SDimitry Andric   assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
7540b57cec5SDimitry Andric 
7550b57cec5SDimitry Andric   // Pass through MD5 if enough work has built up.
7560b57cec5SDimitry Andric   if (Count && Count % NumTypesPerWord == 0) {
7570b57cec5SDimitry Andric     using namespace llvm::support;
758*c9157d92SDimitry Andric     uint64_t Swapped =
759*c9157d92SDimitry Andric         endian::byte_swap<uint64_t, llvm::endianness::little>(Working);
760bdd1243dSDimitry Andric     MD5.update(llvm::ArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
7610b57cec5SDimitry Andric     Working = 0;
7620b57cec5SDimitry Andric   }
7630b57cec5SDimitry Andric 
7640b57cec5SDimitry Andric   // Accumulate the current type.
7650b57cec5SDimitry Andric   ++Count;
7660b57cec5SDimitry Andric   Working = Working << NumBitsPerType | Type;
7670b57cec5SDimitry Andric }
7680b57cec5SDimitry Andric 
7690b57cec5SDimitry Andric uint64_t PGOHash::finalize() {
7700b57cec5SDimitry Andric   // Use Working as the hash directly if we never used MD5.
7710b57cec5SDimitry Andric   if (Count <= NumTypesPerWord)
7720b57cec5SDimitry Andric     // No need to byte swap here, since none of the math was endian-dependent.
7730b57cec5SDimitry Andric     // This number will be byte-swapped as required on endianness transitions,
7740b57cec5SDimitry Andric     // so we will see the same value on the other side.
7750b57cec5SDimitry Andric     return Working;
7760b57cec5SDimitry Andric 
7770b57cec5SDimitry Andric   // Check for remaining work in Working.
7785ffd83dbSDimitry Andric   if (Working) {
7795ffd83dbSDimitry Andric     // Keep the buggy behavior from v1 and v2 for backward-compatibility. This
7805ffd83dbSDimitry Andric     // is buggy because it converts a uint64_t into an array of uint8_t.
7815ffd83dbSDimitry Andric     if (HashVersion < PGO_HASH_V3) {
7825ffd83dbSDimitry Andric       MD5.update({(uint8_t)Working});
7835ffd83dbSDimitry Andric     } else {
7845ffd83dbSDimitry Andric       using namespace llvm::support;
785*c9157d92SDimitry Andric       uint64_t Swapped =
786*c9157d92SDimitry Andric           endian::byte_swap<uint64_t, llvm::endianness::little>(Working);
787bdd1243dSDimitry Andric       MD5.update(llvm::ArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
7885ffd83dbSDimitry Andric     }
7895ffd83dbSDimitry Andric   }
7900b57cec5SDimitry Andric 
7910b57cec5SDimitry Andric   // Finalize the MD5 and return the hash.
7920b57cec5SDimitry Andric   llvm::MD5::MD5Result Result;
7930b57cec5SDimitry Andric   MD5.final(Result);
7940b57cec5SDimitry Andric   return Result.low();
7950b57cec5SDimitry Andric }
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
7980b57cec5SDimitry Andric   const Decl *D = GD.getDecl();
7990b57cec5SDimitry Andric   if (!D->hasBody())
8000b57cec5SDimitry Andric     return;
8010b57cec5SDimitry Andric 
802e8d8bef9SDimitry Andric   // Skip CUDA/HIP kernel launch stub functions.
803e8d8bef9SDimitry Andric   if (CGM.getLangOpts().CUDA && !CGM.getLangOpts().CUDAIsDevice &&
804e8d8bef9SDimitry Andric       D->hasAttr<CUDAGlobalAttr>())
805e8d8bef9SDimitry Andric     return;
806e8d8bef9SDimitry Andric 
8070b57cec5SDimitry Andric   bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
8080b57cec5SDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
8090b57cec5SDimitry Andric   if (!InstrumentRegions && !PGOReader)
8100b57cec5SDimitry Andric     return;
8110b57cec5SDimitry Andric   if (D->isImplicit())
8120b57cec5SDimitry Andric     return;
8130b57cec5SDimitry Andric   // Constructors and destructors may be represented by several functions in IR.
8140b57cec5SDimitry Andric   // If so, instrument only base variant, others are implemented by delegation
8150b57cec5SDimitry Andric   // to the base one, it would be counted twice otherwise.
8160b57cec5SDimitry Andric   if (CGM.getTarget().getCXXABI().hasConstructorVariants()) {
8170b57cec5SDimitry Andric     if (const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
8180b57cec5SDimitry Andric       if (GD.getCtorType() != Ctor_Base &&
8190b57cec5SDimitry Andric           CodeGenFunction::IsConstructorDelegationValid(CCD))
8200b57cec5SDimitry Andric         return;
8210b57cec5SDimitry Andric   }
8220b57cec5SDimitry Andric   if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
8230b57cec5SDimitry Andric     return;
8240b57cec5SDimitry Andric 
825fe6060f1SDimitry Andric   CGM.ClearUnusedCoverageMapping(D);
826e8d8bef9SDimitry Andric   if (Fn->hasFnAttribute(llvm::Attribute::NoProfile))
827e8d8bef9SDimitry Andric     return;
828bdd1243dSDimitry Andric   if (Fn->hasFnAttribute(llvm::Attribute::SkipProfile))
829bdd1243dSDimitry Andric     return;
830e8d8bef9SDimitry Andric 
8310b57cec5SDimitry Andric   setFuncName(Fn);
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric   mapRegionCounters(D);
8340b57cec5SDimitry Andric   if (CGM.getCodeGenOpts().CoverageMapping)
8350b57cec5SDimitry Andric     emitCounterRegionMapping(D);
8360b57cec5SDimitry Andric   if (PGOReader) {
8370b57cec5SDimitry Andric     SourceManager &SM = CGM.getContext().getSourceManager();
8380b57cec5SDimitry Andric     loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
8390b57cec5SDimitry Andric     computeRegionCounts(D);
8400b57cec5SDimitry Andric     applyFunctionAttributes(PGOReader, Fn);
8410b57cec5SDimitry Andric   }
8420b57cec5SDimitry Andric }
8430b57cec5SDimitry Andric 
8440b57cec5SDimitry Andric void CodeGenPGO::mapRegionCounters(const Decl *D) {
8450b57cec5SDimitry Andric   // Use the latest hash version when inserting instrumentation, but use the
8460b57cec5SDimitry Andric   // version in the indexed profile if we're reading PGO data.
8470b57cec5SDimitry Andric   PGOHashVersion HashVersion = PGO_HASH_LATEST;
848e8d8bef9SDimitry Andric   uint64_t ProfileVersion = llvm::IndexedInstrProf::Version;
849e8d8bef9SDimitry Andric   if (auto *PGOReader = CGM.getPGOReader()) {
8500b57cec5SDimitry Andric     HashVersion = getPGOHashVersion(PGOReader, CGM);
851e8d8bef9SDimitry Andric     ProfileVersion = PGOReader->getVersion();
852e8d8bef9SDimitry Andric   }
8530b57cec5SDimitry Andric 
8540b57cec5SDimitry Andric   RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
855e8d8bef9SDimitry Andric   MapRegionCounters Walker(HashVersion, ProfileVersion, *RegionCounterMap);
8560b57cec5SDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
8570b57cec5SDimitry Andric     Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
8580b57cec5SDimitry Andric   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
8590b57cec5SDimitry Andric     Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
8600b57cec5SDimitry Andric   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
8610b57cec5SDimitry Andric     Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
8620b57cec5SDimitry Andric   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
8630b57cec5SDimitry Andric     Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
8640b57cec5SDimitry Andric   assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
8650b57cec5SDimitry Andric   NumRegionCounters = Walker.NextCounter;
8660b57cec5SDimitry Andric   FunctionHash = Walker.Hash.finalize();
8670b57cec5SDimitry Andric }
8680b57cec5SDimitry Andric 
8690b57cec5SDimitry Andric bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) {
8700b57cec5SDimitry Andric   if (!D->getBody())
8710b57cec5SDimitry Andric     return true;
8720b57cec5SDimitry Andric 
873e8d8bef9SDimitry Andric   // Skip host-only functions in the CUDA device compilation and device-only
874e8d8bef9SDimitry Andric   // functions in the host compilation. Just roughly filter them out based on
875e8d8bef9SDimitry Andric   // the function attributes. If there are effectively host-only or device-only
876e8d8bef9SDimitry Andric   // ones, their coverage mapping may still be generated.
877e8d8bef9SDimitry Andric   if (CGM.getLangOpts().CUDA &&
878e8d8bef9SDimitry Andric       ((CGM.getLangOpts().CUDAIsDevice && !D->hasAttr<CUDADeviceAttr>() &&
879e8d8bef9SDimitry Andric         !D->hasAttr<CUDAGlobalAttr>()) ||
880e8d8bef9SDimitry Andric        (!CGM.getLangOpts().CUDAIsDevice &&
881e8d8bef9SDimitry Andric         (D->hasAttr<CUDAGlobalAttr>() ||
882e8d8bef9SDimitry Andric          (!D->hasAttr<CUDAHostAttr>() && D->hasAttr<CUDADeviceAttr>())))))
883e8d8bef9SDimitry Andric     return true;
884e8d8bef9SDimitry Andric 
8850b57cec5SDimitry Andric   // Don't map the functions in system headers.
8860b57cec5SDimitry Andric   const auto &SM = CGM.getContext().getSourceManager();
8870b57cec5SDimitry Andric   auto Loc = D->getBody()->getBeginLoc();
8880b57cec5SDimitry Andric   return SM.isInSystemHeader(Loc);
8890b57cec5SDimitry Andric }
8900b57cec5SDimitry Andric 
8910b57cec5SDimitry Andric void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
8920b57cec5SDimitry Andric   if (skipRegionMappingForDecl(D))
8930b57cec5SDimitry Andric     return;
8940b57cec5SDimitry Andric 
8950b57cec5SDimitry Andric   std::string CoverageMapping;
8960b57cec5SDimitry Andric   llvm::raw_string_ostream OS(CoverageMapping);
8970b57cec5SDimitry Andric   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
8980b57cec5SDimitry Andric                                 CGM.getContext().getSourceManager(),
8990b57cec5SDimitry Andric                                 CGM.getLangOpts(), RegionCounterMap.get());
9000b57cec5SDimitry Andric   MappingGen.emitCounterMapping(D, OS);
9010b57cec5SDimitry Andric   OS.flush();
9020b57cec5SDimitry Andric 
9030b57cec5SDimitry Andric   if (CoverageMapping.empty())
9040b57cec5SDimitry Andric     return;
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric   CGM.getCoverageMapping()->addFunctionMappingRecord(
9070b57cec5SDimitry Andric       FuncNameVar, FuncName, FunctionHash, CoverageMapping);
9080b57cec5SDimitry Andric }
9090b57cec5SDimitry Andric 
9100b57cec5SDimitry Andric void
9110b57cec5SDimitry Andric CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef Name,
9120b57cec5SDimitry Andric                                     llvm::GlobalValue::LinkageTypes Linkage) {
9130b57cec5SDimitry Andric   if (skipRegionMappingForDecl(D))
9140b57cec5SDimitry Andric     return;
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric   std::string CoverageMapping;
9170b57cec5SDimitry Andric   llvm::raw_string_ostream OS(CoverageMapping);
9180b57cec5SDimitry Andric   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
9190b57cec5SDimitry Andric                                 CGM.getContext().getSourceManager(),
9200b57cec5SDimitry Andric                                 CGM.getLangOpts());
9210b57cec5SDimitry Andric   MappingGen.emitEmptyMapping(D, OS);
9220b57cec5SDimitry Andric   OS.flush();
9230b57cec5SDimitry Andric 
9240b57cec5SDimitry Andric   if (CoverageMapping.empty())
9250b57cec5SDimitry Andric     return;
9260b57cec5SDimitry Andric 
9270b57cec5SDimitry Andric   setFuncName(Name, Linkage);
9280b57cec5SDimitry Andric   CGM.getCoverageMapping()->addFunctionMappingRecord(
9290b57cec5SDimitry Andric       FuncNameVar, FuncName, FunctionHash, CoverageMapping, false);
9300b57cec5SDimitry Andric }
9310b57cec5SDimitry Andric 
9320b57cec5SDimitry Andric void CodeGenPGO::computeRegionCounts(const Decl *D) {
9330b57cec5SDimitry Andric   StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
9340b57cec5SDimitry Andric   ComputeRegionCounts Walker(*StmtCountMap, *this);
9350b57cec5SDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
9360b57cec5SDimitry Andric     Walker.VisitFunctionDecl(FD);
9370b57cec5SDimitry Andric   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
9380b57cec5SDimitry Andric     Walker.VisitObjCMethodDecl(MD);
9390b57cec5SDimitry Andric   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
9400b57cec5SDimitry Andric     Walker.VisitBlockDecl(BD);
9410b57cec5SDimitry Andric   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
9420b57cec5SDimitry Andric     Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
9430b57cec5SDimitry Andric }
9440b57cec5SDimitry Andric 
9450b57cec5SDimitry Andric void
9460b57cec5SDimitry Andric CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
9470b57cec5SDimitry Andric                                     llvm::Function *Fn) {
9480b57cec5SDimitry Andric   if (!haveRegionCounts())
9490b57cec5SDimitry Andric     return;
9500b57cec5SDimitry Andric 
9510b57cec5SDimitry Andric   uint64_t FunctionCount = getRegionCount(nullptr);
9520b57cec5SDimitry Andric   Fn->setEntryCount(FunctionCount);
9530b57cec5SDimitry Andric }
9540b57cec5SDimitry Andric 
9550b57cec5SDimitry Andric void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
9560b57cec5SDimitry Andric                                       llvm::Value *StepV) {
957*c9157d92SDimitry Andric   if (!RegionCounterMap || !Builder.GetInsertBlock())
9580b57cec5SDimitry Andric     return;
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric   unsigned Counter = (*RegionCounterMap)[S];
9610b57cec5SDimitry Andric 
962*c9157d92SDimitry Andric   llvm::Value *Args[] = {FuncNameVar,
9630b57cec5SDimitry Andric                          Builder.getInt64(FunctionHash),
9640b57cec5SDimitry Andric                          Builder.getInt32(NumRegionCounters),
9650b57cec5SDimitry Andric                          Builder.getInt32(Counter), StepV};
9660b57cec5SDimitry Andric   if (!StepV)
9670b57cec5SDimitry Andric     Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
968bdd1243dSDimitry Andric                        ArrayRef(Args, 4));
9690b57cec5SDimitry Andric   else
9700b57cec5SDimitry Andric     Builder.CreateCall(
9710b57cec5SDimitry Andric         CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment_step),
972bdd1243dSDimitry Andric         ArrayRef(Args));
9730b57cec5SDimitry Andric }
9740b57cec5SDimitry Andric 
975fe6060f1SDimitry Andric void CodeGenPGO::setValueProfilingFlag(llvm::Module &M) {
976fe6060f1SDimitry Andric   if (CGM.getCodeGenOpts().hasProfileClangInstr())
977fe6060f1SDimitry Andric     M.addModuleFlag(llvm::Module::Warning, "EnableValueProfiling",
978fe6060f1SDimitry Andric                     uint32_t(EnableValueProfiling));
979fe6060f1SDimitry Andric }
980fe6060f1SDimitry Andric 
9810b57cec5SDimitry Andric // This method either inserts a call to the profile run-time during
9820b57cec5SDimitry Andric // instrumentation or puts profile data into metadata for PGO use.
9830b57cec5SDimitry Andric void CodeGenPGO::valueProfile(CGBuilderTy &Builder, uint32_t ValueKind,
9840b57cec5SDimitry Andric     llvm::Instruction *ValueSite, llvm::Value *ValuePtr) {
9850b57cec5SDimitry Andric 
9860b57cec5SDimitry Andric   if (!EnableValueProfiling)
9870b57cec5SDimitry Andric     return;
9880b57cec5SDimitry Andric 
9890b57cec5SDimitry Andric   if (!ValuePtr || !ValueSite || !Builder.GetInsertBlock())
9900b57cec5SDimitry Andric     return;
9910b57cec5SDimitry Andric 
9920b57cec5SDimitry Andric   if (isa<llvm::Constant>(ValuePtr))
9930b57cec5SDimitry Andric     return;
9940b57cec5SDimitry Andric 
9950b57cec5SDimitry Andric   bool InstrumentValueSites = CGM.getCodeGenOpts().hasProfileClangInstr();
9960b57cec5SDimitry Andric   if (InstrumentValueSites && RegionCounterMap) {
9970b57cec5SDimitry Andric     auto BuilderInsertPoint = Builder.saveIP();
9980b57cec5SDimitry Andric     Builder.SetInsertPoint(ValueSite);
9990b57cec5SDimitry Andric     llvm::Value *Args[5] = {
1000*c9157d92SDimitry Andric         FuncNameVar,
10010b57cec5SDimitry Andric         Builder.getInt64(FunctionHash),
10020b57cec5SDimitry Andric         Builder.CreatePtrToInt(ValuePtr, Builder.getInt64Ty()),
10030b57cec5SDimitry Andric         Builder.getInt32(ValueKind),
10040b57cec5SDimitry Andric         Builder.getInt32(NumValueSites[ValueKind]++)
10050b57cec5SDimitry Andric     };
10060b57cec5SDimitry Andric     Builder.CreateCall(
10070b57cec5SDimitry Andric         CGM.getIntrinsic(llvm::Intrinsic::instrprof_value_profile), Args);
10080b57cec5SDimitry Andric     Builder.restoreIP(BuilderInsertPoint);
10090b57cec5SDimitry Andric     return;
10100b57cec5SDimitry Andric   }
10110b57cec5SDimitry Andric 
10120b57cec5SDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
10130b57cec5SDimitry Andric   if (PGOReader && haveRegionCounts()) {
10140b57cec5SDimitry Andric     // We record the top most called three functions at each call site.
10150b57cec5SDimitry Andric     // Profile metadata contains "VP" string identifying this metadata
10160b57cec5SDimitry Andric     // as value profiling data, then a uint32_t value for the value profiling
10170b57cec5SDimitry Andric     // kind, a uint64_t value for the total number of times the call is
10180b57cec5SDimitry Andric     // executed, followed by the function hash and execution count (uint64_t)
10190b57cec5SDimitry Andric     // pairs for each function.
10200b57cec5SDimitry Andric     if (NumValueSites[ValueKind] >= ProfRecord->getNumValueSites(ValueKind))
10210b57cec5SDimitry Andric       return;
10220b57cec5SDimitry Andric 
10230b57cec5SDimitry Andric     llvm::annotateValueSite(CGM.getModule(), *ValueSite, *ProfRecord,
10240b57cec5SDimitry Andric                             (llvm::InstrProfValueKind)ValueKind,
10250b57cec5SDimitry Andric                             NumValueSites[ValueKind]);
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric     NumValueSites[ValueKind]++;
10280b57cec5SDimitry Andric   }
10290b57cec5SDimitry Andric }
10300b57cec5SDimitry Andric 
10310b57cec5SDimitry Andric void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
10320b57cec5SDimitry Andric                                   bool IsInMainFile) {
10330b57cec5SDimitry Andric   CGM.getPGOStats().addVisited(IsInMainFile);
10340b57cec5SDimitry Andric   RegionCounts.clear();
10350b57cec5SDimitry Andric   llvm::Expected<llvm::InstrProfRecord> RecordExpected =
10360b57cec5SDimitry Andric       PGOReader->getInstrProfRecord(FuncName, FunctionHash);
10370b57cec5SDimitry Andric   if (auto E = RecordExpected.takeError()) {
1038fe013be4SDimitry Andric     auto IPE = std::get<0>(llvm::InstrProfError::take(std::move(E)));
10390b57cec5SDimitry Andric     if (IPE == llvm::instrprof_error::unknown_function)
10400b57cec5SDimitry Andric       CGM.getPGOStats().addMissing(IsInMainFile);
10410b57cec5SDimitry Andric     else if (IPE == llvm::instrprof_error::hash_mismatch)
10420b57cec5SDimitry Andric       CGM.getPGOStats().addMismatched(IsInMainFile);
10430b57cec5SDimitry Andric     else if (IPE == llvm::instrprof_error::malformed)
10440b57cec5SDimitry Andric       // TODO: Consider a more specific warning for this case.
10450b57cec5SDimitry Andric       CGM.getPGOStats().addMismatched(IsInMainFile);
10460b57cec5SDimitry Andric     return;
10470b57cec5SDimitry Andric   }
10480b57cec5SDimitry Andric   ProfRecord =
1049a7dea167SDimitry Andric       std::make_unique<llvm::InstrProfRecord>(std::move(RecordExpected.get()));
10500b57cec5SDimitry Andric   RegionCounts = ProfRecord->Counts;
10510b57cec5SDimitry Andric }
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric /// Calculate what to divide by to scale weights.
10540b57cec5SDimitry Andric ///
10550b57cec5SDimitry Andric /// Given the maximum weight, calculate a divisor that will scale all the
10560b57cec5SDimitry Andric /// weights to strictly less than UINT32_MAX.
10570b57cec5SDimitry Andric static uint64_t calculateWeightScale(uint64_t MaxWeight) {
10580b57cec5SDimitry Andric   return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
10590b57cec5SDimitry Andric }
10600b57cec5SDimitry Andric 
10610b57cec5SDimitry Andric /// Scale an individual branch weight (and add 1).
10620b57cec5SDimitry Andric ///
10630b57cec5SDimitry Andric /// Scale a 64-bit weight down to 32-bits using \c Scale.
10640b57cec5SDimitry Andric ///
10650b57cec5SDimitry Andric /// According to Laplace's Rule of Succession, it is better to compute the
10660b57cec5SDimitry Andric /// weight based on the count plus 1, so universally add 1 to the value.
10670b57cec5SDimitry Andric ///
10680b57cec5SDimitry Andric /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
10690b57cec5SDimitry Andric /// greater than \c Weight.
10700b57cec5SDimitry Andric static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
10710b57cec5SDimitry Andric   assert(Scale && "scale by 0?");
10720b57cec5SDimitry Andric   uint64_t Scaled = Weight / Scale + 1;
10730b57cec5SDimitry Andric   assert(Scaled <= UINT32_MAX && "overflow 32-bits");
10740b57cec5SDimitry Andric   return Scaled;
10750b57cec5SDimitry Andric }
10760b57cec5SDimitry Andric 
10770b57cec5SDimitry Andric llvm::MDNode *CodeGenFunction::createProfileWeights(uint64_t TrueCount,
1078e8d8bef9SDimitry Andric                                                     uint64_t FalseCount) const {
10790b57cec5SDimitry Andric   // Check for empty weights.
10800b57cec5SDimitry Andric   if (!TrueCount && !FalseCount)
10810b57cec5SDimitry Andric     return nullptr;
10820b57cec5SDimitry Andric 
10830b57cec5SDimitry Andric   // Calculate how to scale down to 32-bits.
10840b57cec5SDimitry Andric   uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
10850b57cec5SDimitry Andric 
10860b57cec5SDimitry Andric   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
10870b57cec5SDimitry Andric   return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
10880b57cec5SDimitry Andric                                       scaleBranchWeight(FalseCount, Scale));
10890b57cec5SDimitry Andric }
10900b57cec5SDimitry Andric 
10910b57cec5SDimitry Andric llvm::MDNode *
1092e8d8bef9SDimitry Andric CodeGenFunction::createProfileWeights(ArrayRef<uint64_t> Weights) const {
10930b57cec5SDimitry Andric   // We need at least two elements to create meaningful weights.
10940b57cec5SDimitry Andric   if (Weights.size() < 2)
10950b57cec5SDimitry Andric     return nullptr;
10960b57cec5SDimitry Andric 
10970b57cec5SDimitry Andric   // Check for empty weights.
10980b57cec5SDimitry Andric   uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
10990b57cec5SDimitry Andric   if (MaxWeight == 0)
11000b57cec5SDimitry Andric     return nullptr;
11010b57cec5SDimitry Andric 
11020b57cec5SDimitry Andric   // Calculate how to scale down to 32-bits.
11030b57cec5SDimitry Andric   uint64_t Scale = calculateWeightScale(MaxWeight);
11040b57cec5SDimitry Andric 
11050b57cec5SDimitry Andric   SmallVector<uint32_t, 16> ScaledWeights;
11060b57cec5SDimitry Andric   ScaledWeights.reserve(Weights.size());
11070b57cec5SDimitry Andric   for (uint64_t W : Weights)
11080b57cec5SDimitry Andric     ScaledWeights.push_back(scaleBranchWeight(W, Scale));
11090b57cec5SDimitry Andric 
11100b57cec5SDimitry Andric   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
11110b57cec5SDimitry Andric   return MDHelper.createBranchWeights(ScaledWeights);
11120b57cec5SDimitry Andric }
11130b57cec5SDimitry Andric 
1114e8d8bef9SDimitry Andric llvm::MDNode *
1115e8d8bef9SDimitry Andric CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond,
1116e8d8bef9SDimitry Andric                                              uint64_t LoopCount) const {
11170b57cec5SDimitry Andric   if (!PGO.haveRegionCounts())
11180b57cec5SDimitry Andric     return nullptr;
1119bdd1243dSDimitry Andric   std::optional<uint64_t> CondCount = PGO.getStmtCount(Cond);
11205ffd83dbSDimitry Andric   if (!CondCount || *CondCount == 0)
11210b57cec5SDimitry Andric     return nullptr;
11220b57cec5SDimitry Andric   return createProfileWeights(LoopCount,
11230b57cec5SDimitry Andric                               std::max(*CondCount, LoopCount) - LoopCount);
11240b57cec5SDimitry Andric }
1125