159d1ed5bSDimitry Andric //===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- C++ -*-===//
259d1ed5bSDimitry Andric //
359d1ed5bSDimitry Andric //                     The LLVM Compiler Infrastructure
459d1ed5bSDimitry Andric //
559d1ed5bSDimitry Andric // This file is distributed under the University of Illinois Open Source
659d1ed5bSDimitry Andric // License. See LICENSE.TXT for details.
759d1ed5bSDimitry Andric //
859d1ed5bSDimitry Andric //===----------------------------------------------------------------------===//
959d1ed5bSDimitry Andric //
1059d1ed5bSDimitry Andric // Instrumentation-based profile-guided optimization
1159d1ed5bSDimitry Andric //
1259d1ed5bSDimitry Andric //===----------------------------------------------------------------------===//
1359d1ed5bSDimitry Andric 
1459d1ed5bSDimitry Andric #include "CodeGenPGO.h"
1559d1ed5bSDimitry Andric #include "CodeGenFunction.h"
1639d628a0SDimitry Andric #include "CoverageMappingGen.h"
1759d1ed5bSDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
1859d1ed5bSDimitry Andric #include "clang/AST/StmtVisitor.h"
1939d628a0SDimitry Andric #include "llvm/IR/Intrinsics.h"
2059d1ed5bSDimitry Andric #include "llvm/IR/MDBuilder.h"
2159d1ed5bSDimitry Andric #include "llvm/Support/Endian.h"
2259d1ed5bSDimitry Andric #include "llvm/Support/FileSystem.h"
2359d1ed5bSDimitry Andric #include "llvm/Support/MD5.h"
2459d1ed5bSDimitry Andric 
259a199699SDimitry Andric static llvm::cl::opt<bool>
269a199699SDimitry Andric     EnableValueProfiling("enable-value-profiling", llvm::cl::ZeroOrMore,
279a199699SDimitry Andric                          llvm::cl::desc("Enable value profiling"),
289a199699SDimitry Andric                          llvm::cl::Hidden, llvm::cl::init(false));
29e7145dcbSDimitry Andric 
3059d1ed5bSDimitry Andric using namespace clang;
3159d1ed5bSDimitry Andric using namespace CodeGen;
3259d1ed5bSDimitry Andric 
setFuncName(StringRef Name,llvm::GlobalValue::LinkageTypes Linkage)3339d628a0SDimitry Andric void CodeGenPGO::setFuncName(StringRef Name,
3439d628a0SDimitry Andric                              llvm::GlobalValue::LinkageTypes Linkage) {
350623d748SDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
360623d748SDimitry Andric   FuncName = llvm::getPGOFuncName(
370623d748SDimitry Andric       Name, Linkage, CGM.getCodeGenOpts().MainFileName,
380623d748SDimitry Andric       PGOReader ? PGOReader->getVersion() : llvm::IndexedInstrProf::Version);
3959d1ed5bSDimitry Andric 
4039d628a0SDimitry Andric   // If we're generating a profile, create a variable for the name.
41e7145dcbSDimitry Andric   if (CGM.getCodeGenOpts().hasProfileClangInstr())
420623d748SDimitry Andric     FuncNameVar = llvm::createPGOFuncNameVar(CGM.getModule(), Linkage, FuncName);
4359d1ed5bSDimitry Andric }
4459d1ed5bSDimitry Andric 
setFuncName(llvm::Function * Fn)4539d628a0SDimitry Andric void CodeGenPGO::setFuncName(llvm::Function *Fn) {
4639d628a0SDimitry Andric   setFuncName(Fn->getName(), Fn->getLinkage());
47e7145dcbSDimitry Andric   // Create PGOFuncName meta data.
48e7145dcbSDimitry Andric   llvm::createPGOFuncNameMetadata(*Fn, FuncName);
4959d1ed5bSDimitry Andric }
5059d1ed5bSDimitry Andric 
519a199699SDimitry Andric /// The version of the PGO hash algorithm.
529a199699SDimitry Andric enum PGOHashVersion : unsigned {
539a199699SDimitry Andric   PGO_HASH_V1,
549a199699SDimitry Andric   PGO_HASH_V2,
559a199699SDimitry Andric 
569a199699SDimitry Andric   // Keep this set to the latest hash version.
579a199699SDimitry Andric   PGO_HASH_LATEST = PGO_HASH_V2
589a199699SDimitry Andric };
599a199699SDimitry Andric 
6059d1ed5bSDimitry Andric namespace {
614ba319b5SDimitry Andric /// Stable hasher for PGO region counters.
6259d1ed5bSDimitry Andric ///
6359d1ed5bSDimitry Andric /// PGOHash produces a stable hash of a given function's control flow.
6459d1ed5bSDimitry Andric ///
6559d1ed5bSDimitry Andric /// Changing the output of this hash will invalidate all previously generated
6659d1ed5bSDimitry Andric /// profiles -- i.e., don't do it.
6759d1ed5bSDimitry Andric ///
6859d1ed5bSDimitry Andric /// \note  When this hash does eventually change (years?), we still need to
6959d1ed5bSDimitry Andric /// support old hashes.  We'll need to pull in the version number from the
7059d1ed5bSDimitry Andric /// profile data format and use the matching hash function.
7159d1ed5bSDimitry Andric class PGOHash {
7259d1ed5bSDimitry Andric   uint64_t Working;
7359d1ed5bSDimitry Andric   unsigned Count;
749a199699SDimitry Andric   PGOHashVersion HashVersion;
7559d1ed5bSDimitry Andric   llvm::MD5 MD5;
7659d1ed5bSDimitry Andric 
7759d1ed5bSDimitry Andric   static const int NumBitsPerType = 6;
7859d1ed5bSDimitry Andric   static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
7959d1ed5bSDimitry Andric   static const unsigned TooBig = 1u << NumBitsPerType;
8059d1ed5bSDimitry Andric 
8159d1ed5bSDimitry Andric public:
824ba319b5SDimitry Andric   /// Hash values for AST nodes.
8359d1ed5bSDimitry Andric   ///
8459d1ed5bSDimitry Andric   /// Distinct values for AST nodes that have region counters attached.
8559d1ed5bSDimitry Andric   ///
8659d1ed5bSDimitry Andric   /// These values must be stable.  All new members must be added at the end,
8759d1ed5bSDimitry Andric   /// and no members should be removed.  Changing the enumeration value for an
8859d1ed5bSDimitry Andric   /// AST node will affect the hash of every function that contains that node.
8959d1ed5bSDimitry Andric   enum HashType : unsigned char {
9059d1ed5bSDimitry Andric     None = 0,
9159d1ed5bSDimitry Andric     LabelStmt = 1,
9259d1ed5bSDimitry Andric     WhileStmt,
9359d1ed5bSDimitry Andric     DoStmt,
9459d1ed5bSDimitry Andric     ForStmt,
9559d1ed5bSDimitry Andric     CXXForRangeStmt,
9659d1ed5bSDimitry Andric     ObjCForCollectionStmt,
9759d1ed5bSDimitry Andric     SwitchStmt,
9859d1ed5bSDimitry Andric     CaseStmt,
9959d1ed5bSDimitry Andric     DefaultStmt,
10059d1ed5bSDimitry Andric     IfStmt,
10159d1ed5bSDimitry Andric     CXXTryStmt,
10259d1ed5bSDimitry Andric     CXXCatchStmt,
10359d1ed5bSDimitry Andric     ConditionalOperator,
10459d1ed5bSDimitry Andric     BinaryOperatorLAnd,
10559d1ed5bSDimitry Andric     BinaryOperatorLOr,
10659d1ed5bSDimitry Andric     BinaryConditionalOperator,
1079a199699SDimitry Andric     // The preceding values are available with PGO_HASH_V1.
1089a199699SDimitry Andric 
1099a199699SDimitry Andric     EndOfScope,
1109a199699SDimitry Andric     IfThenBranch,
1119a199699SDimitry Andric     IfElseBranch,
1129a199699SDimitry Andric     GotoStmt,
1139a199699SDimitry Andric     IndirectGotoStmt,
1149a199699SDimitry Andric     BreakStmt,
1159a199699SDimitry Andric     ContinueStmt,
1169a199699SDimitry Andric     ReturnStmt,
1179a199699SDimitry Andric     ThrowExpr,
1189a199699SDimitry Andric     UnaryOperatorLNot,
1199a199699SDimitry Andric     BinaryOperatorLT,
1209a199699SDimitry Andric     BinaryOperatorGT,
1219a199699SDimitry Andric     BinaryOperatorLE,
1229a199699SDimitry Andric     BinaryOperatorGE,
1239a199699SDimitry Andric     BinaryOperatorEQ,
1249a199699SDimitry Andric     BinaryOperatorNE,
1259a199699SDimitry Andric     // The preceding values are available with PGO_HASH_V2.
12659d1ed5bSDimitry Andric 
12759d1ed5bSDimitry Andric     // Keep this last.  It's for the static assert that follows.
12859d1ed5bSDimitry Andric     LastHashType
12959d1ed5bSDimitry Andric   };
13059d1ed5bSDimitry Andric   static_assert(LastHashType <= TooBig, "Too many types in HashType");
13159d1ed5bSDimitry Andric 
PGOHash(PGOHashVersion HashVersion)1329a199699SDimitry Andric   PGOHash(PGOHashVersion HashVersion)
1339a199699SDimitry Andric       : Working(0), Count(0), HashVersion(HashVersion), MD5() {}
13459d1ed5bSDimitry Andric   void combine(HashType Type);
13559d1ed5bSDimitry Andric   uint64_t finalize();
getHashVersion() const1369a199699SDimitry Andric   PGOHashVersion getHashVersion() const { return HashVersion; }
13759d1ed5bSDimitry Andric };
13859d1ed5bSDimitry Andric const int PGOHash::NumBitsPerType;
13959d1ed5bSDimitry Andric const unsigned PGOHash::NumTypesPerWord;
14059d1ed5bSDimitry Andric const unsigned PGOHash::TooBig;
14159d1ed5bSDimitry Andric 
1429a199699SDimitry Andric /// Get the PGO hash version used in the given indexed profile.
getPGOHashVersion(llvm::IndexedInstrProfReader * PGOReader,CodeGenModule & CGM)1439a199699SDimitry Andric static PGOHashVersion getPGOHashVersion(llvm::IndexedInstrProfReader *PGOReader,
1449a199699SDimitry Andric                                         CodeGenModule &CGM) {
1459a199699SDimitry Andric   if (PGOReader->getVersion() <= 4)
1469a199699SDimitry Andric     return PGO_HASH_V1;
1479a199699SDimitry Andric   return PGO_HASH_V2;
1489a199699SDimitry Andric }
1499a199699SDimitry Andric 
15059d1ed5bSDimitry Andric /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
15159d1ed5bSDimitry Andric struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
1529a199699SDimitry Andric   using Base = RecursiveASTVisitor<MapRegionCounters>;
1539a199699SDimitry Andric 
15459d1ed5bSDimitry Andric   /// The next counter value to assign.
15559d1ed5bSDimitry Andric   unsigned NextCounter;
15659d1ed5bSDimitry Andric   /// The function hash.
15759d1ed5bSDimitry Andric   PGOHash Hash;
15859d1ed5bSDimitry Andric   /// The map of statements to counters.
15959d1ed5bSDimitry Andric   llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
16059d1ed5bSDimitry Andric 
MapRegionCounters__anon67ae45280111::MapRegionCounters1619a199699SDimitry Andric   MapRegionCounters(PGOHashVersion HashVersion,
1629a199699SDimitry Andric                     llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
1639a199699SDimitry Andric       : NextCounter(0), Hash(HashVersion), CounterMap(CounterMap) {}
16459d1ed5bSDimitry Andric 
16559d1ed5bSDimitry Andric   // Blocks and lambdas are handled as separate functions, so we need not
16659d1ed5bSDimitry Andric   // traverse them in the parent context.
TraverseBlockExpr__anon67ae45280111::MapRegionCounters16759d1ed5bSDimitry Andric   bool TraverseBlockExpr(BlockExpr *BE) { return true; }
TraverseLambdaExpr__anon67ae45280111::MapRegionCounters168*b5893f02SDimitry Andric   bool TraverseLambdaExpr(LambdaExpr *LE) {
169*b5893f02SDimitry Andric     // Traverse the captures, but not the body.
170*b5893f02SDimitry Andric     for (const auto &C : zip(LE->captures(), LE->capture_inits()))
171*b5893f02SDimitry Andric       TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
172*b5893f02SDimitry Andric     return true;
173*b5893f02SDimitry Andric   }
TraverseCapturedStmt__anon67ae45280111::MapRegionCounters17459d1ed5bSDimitry Andric   bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
17559d1ed5bSDimitry Andric 
VisitDecl__anon67ae45280111::MapRegionCounters17659d1ed5bSDimitry Andric   bool VisitDecl(const Decl *D) {
17759d1ed5bSDimitry Andric     switch (D->getKind()) {
17859d1ed5bSDimitry Andric     default:
17959d1ed5bSDimitry Andric       break;
18059d1ed5bSDimitry Andric     case Decl::Function:
18159d1ed5bSDimitry Andric     case Decl::CXXMethod:
18259d1ed5bSDimitry Andric     case Decl::CXXConstructor:
18359d1ed5bSDimitry Andric     case Decl::CXXDestructor:
18459d1ed5bSDimitry Andric     case Decl::CXXConversion:
18559d1ed5bSDimitry Andric     case Decl::ObjCMethod:
18659d1ed5bSDimitry Andric     case Decl::Block:
18759d1ed5bSDimitry Andric     case Decl::Captured:
18859d1ed5bSDimitry Andric       CounterMap[D->getBody()] = NextCounter++;
18959d1ed5bSDimitry Andric       break;
19059d1ed5bSDimitry Andric     }
19159d1ed5bSDimitry Andric     return true;
19259d1ed5bSDimitry Andric   }
19359d1ed5bSDimitry Andric 
1949a199699SDimitry Andric   /// If \p S gets a fresh counter, update the counter mappings. Return the
1959a199699SDimitry Andric   /// V1 hash of \p S.
updateCounterMappings__anon67ae45280111::MapRegionCounters1969a199699SDimitry Andric   PGOHash::HashType updateCounterMappings(Stmt *S) {
1979a199699SDimitry Andric     auto Type = getHashType(PGO_HASH_V1, S);
1989a199699SDimitry Andric     if (Type != PGOHash::None)
19959d1ed5bSDimitry Andric       CounterMap[S] = NextCounter++;
2009a199699SDimitry Andric     return Type;
2019a199699SDimitry Andric   }
2029a199699SDimitry Andric 
2039a199699SDimitry Andric   /// Include \p S in the function hash.
VisitStmt__anon67ae45280111::MapRegionCounters2049a199699SDimitry Andric   bool VisitStmt(Stmt *S) {
2059a199699SDimitry Andric     auto Type = updateCounterMappings(S);
2069a199699SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
2079a199699SDimitry Andric       Type = getHashType(Hash.getHashVersion(), S);
2089a199699SDimitry Andric     if (Type != PGOHash::None)
20959d1ed5bSDimitry Andric       Hash.combine(Type);
21059d1ed5bSDimitry Andric     return true;
21159d1ed5bSDimitry Andric   }
2129a199699SDimitry Andric 
TraverseIfStmt__anon67ae45280111::MapRegionCounters2139a199699SDimitry Andric   bool TraverseIfStmt(IfStmt *If) {
2149a199699SDimitry Andric     // If we used the V1 hash, use the default traversal.
2159a199699SDimitry Andric     if (Hash.getHashVersion() == PGO_HASH_V1)
2169a199699SDimitry Andric       return Base::TraverseIfStmt(If);
2179a199699SDimitry Andric 
2189a199699SDimitry Andric     // Otherwise, keep track of which branch we're in while traversing.
2199a199699SDimitry Andric     VisitStmt(If);
2209a199699SDimitry Andric     for (Stmt *CS : If->children()) {
2219a199699SDimitry Andric       if (!CS)
2229a199699SDimitry Andric         continue;
2239a199699SDimitry Andric       if (CS == If->getThen())
2249a199699SDimitry Andric         Hash.combine(PGOHash::IfThenBranch);
2259a199699SDimitry Andric       else if (CS == If->getElse())
2269a199699SDimitry Andric         Hash.combine(PGOHash::IfElseBranch);
2279a199699SDimitry Andric       TraverseStmt(CS);
2289a199699SDimitry Andric     }
2299a199699SDimitry Andric     Hash.combine(PGOHash::EndOfScope);
2309a199699SDimitry Andric     return true;
2319a199699SDimitry Andric   }
2329a199699SDimitry Andric 
2339a199699SDimitry Andric // If the statement type \p N is nestable, and its nesting impacts profile
2349a199699SDimitry Andric // stability, define a custom traversal which tracks the end of the statement
2359a199699SDimitry Andric // in the hash (provided we're not using the V1 hash).
2369a199699SDimitry Andric #define DEFINE_NESTABLE_TRAVERSAL(N)                                           \
2379a199699SDimitry Andric   bool Traverse##N(N *S) {                                                     \
2389a199699SDimitry Andric     Base::Traverse##N(S);                                                      \
2399a199699SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)                                  \
2409a199699SDimitry Andric       Hash.combine(PGOHash::EndOfScope);                                       \
2419a199699SDimitry Andric     return true;                                                               \
2429a199699SDimitry Andric   }
2439a199699SDimitry Andric 
2449a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(WhileStmt)
DEFINE_NESTABLE_TRAVERSAL__anon67ae45280111::MapRegionCounters2459a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(DoStmt)
2469a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(ForStmt)
2479a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXForRangeStmt)
2489a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(ObjCForCollectionStmt)
2499a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXTryStmt)
2509a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXCatchStmt)
2519a199699SDimitry Andric 
2529a199699SDimitry Andric   /// Get version \p HashVersion of the PGO hash for \p S.
2539a199699SDimitry Andric   PGOHash::HashType getHashType(PGOHashVersion HashVersion, const Stmt *S) {
25459d1ed5bSDimitry Andric     switch (S->getStmtClass()) {
25559d1ed5bSDimitry Andric     default:
25659d1ed5bSDimitry Andric       break;
25759d1ed5bSDimitry Andric     case Stmt::LabelStmtClass:
25859d1ed5bSDimitry Andric       return PGOHash::LabelStmt;
25959d1ed5bSDimitry Andric     case Stmt::WhileStmtClass:
26059d1ed5bSDimitry Andric       return PGOHash::WhileStmt;
26159d1ed5bSDimitry Andric     case Stmt::DoStmtClass:
26259d1ed5bSDimitry Andric       return PGOHash::DoStmt;
26359d1ed5bSDimitry Andric     case Stmt::ForStmtClass:
26459d1ed5bSDimitry Andric       return PGOHash::ForStmt;
26559d1ed5bSDimitry Andric     case Stmt::CXXForRangeStmtClass:
26659d1ed5bSDimitry Andric       return PGOHash::CXXForRangeStmt;
26759d1ed5bSDimitry Andric     case Stmt::ObjCForCollectionStmtClass:
26859d1ed5bSDimitry Andric       return PGOHash::ObjCForCollectionStmt;
26959d1ed5bSDimitry Andric     case Stmt::SwitchStmtClass:
27059d1ed5bSDimitry Andric       return PGOHash::SwitchStmt;
27159d1ed5bSDimitry Andric     case Stmt::CaseStmtClass:
27259d1ed5bSDimitry Andric       return PGOHash::CaseStmt;
27359d1ed5bSDimitry Andric     case Stmt::DefaultStmtClass:
27459d1ed5bSDimitry Andric       return PGOHash::DefaultStmt;
27559d1ed5bSDimitry Andric     case Stmt::IfStmtClass:
27659d1ed5bSDimitry Andric       return PGOHash::IfStmt;
27759d1ed5bSDimitry Andric     case Stmt::CXXTryStmtClass:
27859d1ed5bSDimitry Andric       return PGOHash::CXXTryStmt;
27959d1ed5bSDimitry Andric     case Stmt::CXXCatchStmtClass:
28059d1ed5bSDimitry Andric       return PGOHash::CXXCatchStmt;
28159d1ed5bSDimitry Andric     case Stmt::ConditionalOperatorClass:
28259d1ed5bSDimitry Andric       return PGOHash::ConditionalOperator;
28359d1ed5bSDimitry Andric     case Stmt::BinaryConditionalOperatorClass:
28459d1ed5bSDimitry Andric       return PGOHash::BinaryConditionalOperator;
28559d1ed5bSDimitry Andric     case Stmt::BinaryOperatorClass: {
28659d1ed5bSDimitry Andric       const BinaryOperator *BO = cast<BinaryOperator>(S);
28759d1ed5bSDimitry Andric       if (BO->getOpcode() == BO_LAnd)
28859d1ed5bSDimitry Andric         return PGOHash::BinaryOperatorLAnd;
28959d1ed5bSDimitry Andric       if (BO->getOpcode() == BO_LOr)
29059d1ed5bSDimitry Andric         return PGOHash::BinaryOperatorLOr;
2919a199699SDimitry Andric       if (HashVersion == PGO_HASH_V2) {
2929a199699SDimitry Andric         switch (BO->getOpcode()) {
2939a199699SDimitry Andric         default:
2949a199699SDimitry Andric           break;
2959a199699SDimitry Andric         case BO_LT:
2969a199699SDimitry Andric           return PGOHash::BinaryOperatorLT;
2979a199699SDimitry Andric         case BO_GT:
2989a199699SDimitry Andric           return PGOHash::BinaryOperatorGT;
2999a199699SDimitry Andric         case BO_LE:
3009a199699SDimitry Andric           return PGOHash::BinaryOperatorLE;
3019a199699SDimitry Andric         case BO_GE:
3029a199699SDimitry Andric           return PGOHash::BinaryOperatorGE;
3039a199699SDimitry Andric         case BO_EQ:
3049a199699SDimitry Andric           return PGOHash::BinaryOperatorEQ;
3059a199699SDimitry Andric         case BO_NE:
3069a199699SDimitry Andric           return PGOHash::BinaryOperatorNE;
3079a199699SDimitry Andric         }
3089a199699SDimitry Andric       }
30959d1ed5bSDimitry Andric       break;
31059d1ed5bSDimitry Andric     }
31159d1ed5bSDimitry Andric     }
3129a199699SDimitry Andric 
3139a199699SDimitry Andric     if (HashVersion == PGO_HASH_V2) {
3149a199699SDimitry Andric       switch (S->getStmtClass()) {
3159a199699SDimitry Andric       default:
3169a199699SDimitry Andric         break;
3179a199699SDimitry Andric       case Stmt::GotoStmtClass:
3189a199699SDimitry Andric         return PGOHash::GotoStmt;
3199a199699SDimitry Andric       case Stmt::IndirectGotoStmtClass:
3209a199699SDimitry Andric         return PGOHash::IndirectGotoStmt;
3219a199699SDimitry Andric       case Stmt::BreakStmtClass:
3229a199699SDimitry Andric         return PGOHash::BreakStmt;
3239a199699SDimitry Andric       case Stmt::ContinueStmtClass:
3249a199699SDimitry Andric         return PGOHash::ContinueStmt;
3259a199699SDimitry Andric       case Stmt::ReturnStmtClass:
3269a199699SDimitry Andric         return PGOHash::ReturnStmt;
3279a199699SDimitry Andric       case Stmt::CXXThrowExprClass:
3289a199699SDimitry Andric         return PGOHash::ThrowExpr;
3299a199699SDimitry Andric       case Stmt::UnaryOperatorClass: {
3309a199699SDimitry Andric         const UnaryOperator *UO = cast<UnaryOperator>(S);
3319a199699SDimitry Andric         if (UO->getOpcode() == UO_LNot)
3329a199699SDimitry Andric           return PGOHash::UnaryOperatorLNot;
3339a199699SDimitry Andric         break;
3349a199699SDimitry Andric       }
3359a199699SDimitry Andric       }
3369a199699SDimitry Andric     }
3379a199699SDimitry Andric 
33859d1ed5bSDimitry Andric     return PGOHash::None;
33959d1ed5bSDimitry Andric   }
34059d1ed5bSDimitry Andric };
34159d1ed5bSDimitry Andric 
34259d1ed5bSDimitry Andric /// A StmtVisitor that propagates the raw counts through the AST and
34359d1ed5bSDimitry Andric /// records the count at statements where the value may change.
34459d1ed5bSDimitry Andric struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
34559d1ed5bSDimitry Andric   /// PGO state.
34659d1ed5bSDimitry Andric   CodeGenPGO &PGO;
34759d1ed5bSDimitry Andric 
34859d1ed5bSDimitry Andric   /// A flag that is set when the current count should be recorded on the
34959d1ed5bSDimitry Andric   /// next statement, such as at the exit of a loop.
35059d1ed5bSDimitry Andric   bool RecordNextStmtCount;
35159d1ed5bSDimitry Andric 
35233956c43SDimitry Andric   /// The count at the current location in the traversal.
35333956c43SDimitry Andric   uint64_t CurrentCount;
35433956c43SDimitry Andric 
35559d1ed5bSDimitry Andric   /// The map of statements to count values.
35659d1ed5bSDimitry Andric   llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
35759d1ed5bSDimitry Andric 
35859d1ed5bSDimitry Andric   /// BreakContinueStack - Keep counts of breaks and continues inside loops.
35959d1ed5bSDimitry Andric   struct BreakContinue {
36059d1ed5bSDimitry Andric     uint64_t BreakCount;
36159d1ed5bSDimitry Andric     uint64_t ContinueCount;
BreakContinue__anon67ae45280111::ComputeRegionCounts::BreakContinue36259d1ed5bSDimitry Andric     BreakContinue() : BreakCount(0), ContinueCount(0) {}
36359d1ed5bSDimitry Andric   };
36459d1ed5bSDimitry Andric   SmallVector<BreakContinue, 8> BreakContinueStack;
36559d1ed5bSDimitry Andric 
ComputeRegionCounts__anon67ae45280111::ComputeRegionCounts36659d1ed5bSDimitry Andric   ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
36759d1ed5bSDimitry Andric                       CodeGenPGO &PGO)
36859d1ed5bSDimitry Andric       : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
36959d1ed5bSDimitry Andric 
RecordStmtCount__anon67ae45280111::ComputeRegionCounts37059d1ed5bSDimitry Andric   void RecordStmtCount(const Stmt *S) {
37159d1ed5bSDimitry Andric     if (RecordNextStmtCount) {
37233956c43SDimitry Andric       CountMap[S] = CurrentCount;
37359d1ed5bSDimitry Andric       RecordNextStmtCount = false;
37459d1ed5bSDimitry Andric     }
37559d1ed5bSDimitry Andric   }
37659d1ed5bSDimitry Andric 
37733956c43SDimitry Andric   /// Set and return the current count.
setCount__anon67ae45280111::ComputeRegionCounts37833956c43SDimitry Andric   uint64_t setCount(uint64_t Count) {
37933956c43SDimitry Andric     CurrentCount = Count;
38033956c43SDimitry Andric     return Count;
38133956c43SDimitry Andric   }
38233956c43SDimitry Andric 
VisitStmt__anon67ae45280111::ComputeRegionCounts38359d1ed5bSDimitry Andric   void VisitStmt(const Stmt *S) {
38459d1ed5bSDimitry Andric     RecordStmtCount(S);
3853dac3a9bSDimitry Andric     for (const Stmt *Child : S->children())
3863dac3a9bSDimitry Andric       if (Child)
3873dac3a9bSDimitry Andric         this->Visit(Child);
38859d1ed5bSDimitry Andric   }
38959d1ed5bSDimitry Andric 
VisitFunctionDecl__anon67ae45280111::ComputeRegionCounts39059d1ed5bSDimitry Andric   void VisitFunctionDecl(const FunctionDecl *D) {
39159d1ed5bSDimitry Andric     // Counter tracks entry to the function body.
39233956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
39333956c43SDimitry Andric     CountMap[D->getBody()] = BodyCount;
39459d1ed5bSDimitry Andric     Visit(D->getBody());
39559d1ed5bSDimitry Andric   }
39659d1ed5bSDimitry Andric 
39759d1ed5bSDimitry Andric   // Skip lambda expressions. We visit these as FunctionDecls when we're
39859d1ed5bSDimitry Andric   // generating them and aren't interested in the body when generating a
39959d1ed5bSDimitry Andric   // parent context.
VisitLambdaExpr__anon67ae45280111::ComputeRegionCounts40059d1ed5bSDimitry Andric   void VisitLambdaExpr(const LambdaExpr *LE) {}
40159d1ed5bSDimitry Andric 
VisitCapturedDecl__anon67ae45280111::ComputeRegionCounts40259d1ed5bSDimitry Andric   void VisitCapturedDecl(const CapturedDecl *D) {
40359d1ed5bSDimitry Andric     // Counter tracks entry to the capture body.
40433956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
40533956c43SDimitry Andric     CountMap[D->getBody()] = BodyCount;
40659d1ed5bSDimitry Andric     Visit(D->getBody());
40759d1ed5bSDimitry Andric   }
40859d1ed5bSDimitry Andric 
VisitObjCMethodDecl__anon67ae45280111::ComputeRegionCounts40959d1ed5bSDimitry Andric   void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
41059d1ed5bSDimitry Andric     // Counter tracks entry to the method body.
41133956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
41233956c43SDimitry Andric     CountMap[D->getBody()] = BodyCount;
41359d1ed5bSDimitry Andric     Visit(D->getBody());
41459d1ed5bSDimitry Andric   }
41559d1ed5bSDimitry Andric 
VisitBlockDecl__anon67ae45280111::ComputeRegionCounts41659d1ed5bSDimitry Andric   void VisitBlockDecl(const BlockDecl *D) {
41759d1ed5bSDimitry Andric     // Counter tracks entry to the block body.
41833956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
41933956c43SDimitry Andric     CountMap[D->getBody()] = BodyCount;
42059d1ed5bSDimitry Andric     Visit(D->getBody());
42159d1ed5bSDimitry Andric   }
42259d1ed5bSDimitry Andric 
VisitReturnStmt__anon67ae45280111::ComputeRegionCounts42359d1ed5bSDimitry Andric   void VisitReturnStmt(const ReturnStmt *S) {
42459d1ed5bSDimitry Andric     RecordStmtCount(S);
42559d1ed5bSDimitry Andric     if (S->getRetValue())
42659d1ed5bSDimitry Andric       Visit(S->getRetValue());
42733956c43SDimitry Andric     CurrentCount = 0;
42833956c43SDimitry Andric     RecordNextStmtCount = true;
42933956c43SDimitry Andric   }
43033956c43SDimitry Andric 
VisitCXXThrowExpr__anon67ae45280111::ComputeRegionCounts43133956c43SDimitry Andric   void VisitCXXThrowExpr(const CXXThrowExpr *E) {
43233956c43SDimitry Andric     RecordStmtCount(E);
43333956c43SDimitry Andric     if (E->getSubExpr())
43433956c43SDimitry Andric       Visit(E->getSubExpr());
43533956c43SDimitry Andric     CurrentCount = 0;
43659d1ed5bSDimitry Andric     RecordNextStmtCount = true;
43759d1ed5bSDimitry Andric   }
43859d1ed5bSDimitry Andric 
VisitGotoStmt__anon67ae45280111::ComputeRegionCounts43959d1ed5bSDimitry Andric   void VisitGotoStmt(const GotoStmt *S) {
44059d1ed5bSDimitry Andric     RecordStmtCount(S);
44133956c43SDimitry Andric     CurrentCount = 0;
44259d1ed5bSDimitry Andric     RecordNextStmtCount = true;
44359d1ed5bSDimitry Andric   }
44459d1ed5bSDimitry Andric 
VisitLabelStmt__anon67ae45280111::ComputeRegionCounts44559d1ed5bSDimitry Andric   void VisitLabelStmt(const LabelStmt *S) {
44659d1ed5bSDimitry Andric     RecordNextStmtCount = false;
44759d1ed5bSDimitry Andric     // Counter tracks the block following the label.
44833956c43SDimitry Andric     uint64_t BlockCount = setCount(PGO.getRegionCount(S));
44933956c43SDimitry Andric     CountMap[S] = BlockCount;
45059d1ed5bSDimitry Andric     Visit(S->getSubStmt());
45159d1ed5bSDimitry Andric   }
45259d1ed5bSDimitry Andric 
VisitBreakStmt__anon67ae45280111::ComputeRegionCounts45359d1ed5bSDimitry Andric   void VisitBreakStmt(const BreakStmt *S) {
45459d1ed5bSDimitry Andric     RecordStmtCount(S);
45559d1ed5bSDimitry Andric     assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
45633956c43SDimitry Andric     BreakContinueStack.back().BreakCount += CurrentCount;
45733956c43SDimitry Andric     CurrentCount = 0;
45859d1ed5bSDimitry Andric     RecordNextStmtCount = true;
45959d1ed5bSDimitry Andric   }
46059d1ed5bSDimitry Andric 
VisitContinueStmt__anon67ae45280111::ComputeRegionCounts46159d1ed5bSDimitry Andric   void VisitContinueStmt(const ContinueStmt *S) {
46259d1ed5bSDimitry Andric     RecordStmtCount(S);
46359d1ed5bSDimitry Andric     assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
46433956c43SDimitry Andric     BreakContinueStack.back().ContinueCount += CurrentCount;
46533956c43SDimitry Andric     CurrentCount = 0;
46659d1ed5bSDimitry Andric     RecordNextStmtCount = true;
46759d1ed5bSDimitry Andric   }
46859d1ed5bSDimitry Andric 
VisitWhileStmt__anon67ae45280111::ComputeRegionCounts46959d1ed5bSDimitry Andric   void VisitWhileStmt(const WhileStmt *S) {
47059d1ed5bSDimitry Andric     RecordStmtCount(S);
47133956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
47233956c43SDimitry Andric 
47359d1ed5bSDimitry Andric     BreakContinueStack.push_back(BreakContinue());
47459d1ed5bSDimitry Andric     // Visit the body region first so the break/continue adjustments can be
47559d1ed5bSDimitry Andric     // included when visiting the condition.
47633956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
47733956c43SDimitry Andric     CountMap[S->getBody()] = CurrentCount;
47859d1ed5bSDimitry Andric     Visit(S->getBody());
47933956c43SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
48059d1ed5bSDimitry Andric 
48159d1ed5bSDimitry Andric     // ...then go back and propagate counts through the condition. The count
48259d1ed5bSDimitry Andric     // at the start of the condition is the sum of the incoming edges,
48359d1ed5bSDimitry Andric     // the backedge from the end of the loop body, and the edges from
48459d1ed5bSDimitry Andric     // continue statements.
48559d1ed5bSDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
48633956c43SDimitry Andric     uint64_t CondCount =
48733956c43SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
48833956c43SDimitry Andric     CountMap[S->getCond()] = CondCount;
48959d1ed5bSDimitry Andric     Visit(S->getCond());
49033956c43SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
49159d1ed5bSDimitry Andric     RecordNextStmtCount = true;
49259d1ed5bSDimitry Andric   }
49359d1ed5bSDimitry Andric 
VisitDoStmt__anon67ae45280111::ComputeRegionCounts49459d1ed5bSDimitry Andric   void VisitDoStmt(const DoStmt *S) {
49559d1ed5bSDimitry Andric     RecordStmtCount(S);
49633956c43SDimitry Andric     uint64_t LoopCount = PGO.getRegionCount(S);
49733956c43SDimitry Andric 
49859d1ed5bSDimitry Andric     BreakContinueStack.push_back(BreakContinue());
49933956c43SDimitry Andric     // The count doesn't include the fallthrough from the parent scope. Add it.
50033956c43SDimitry Andric     uint64_t BodyCount = setCount(LoopCount + CurrentCount);
50133956c43SDimitry Andric     CountMap[S->getBody()] = BodyCount;
50259d1ed5bSDimitry Andric     Visit(S->getBody());
50333956c43SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
50459d1ed5bSDimitry Andric 
50559d1ed5bSDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
50659d1ed5bSDimitry Andric     // The count at the start of the condition is equal to the count at the
50733956c43SDimitry Andric     // end of the body, plus any continues.
50833956c43SDimitry Andric     uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount);
50933956c43SDimitry Andric     CountMap[S->getCond()] = CondCount;
51059d1ed5bSDimitry Andric     Visit(S->getCond());
51133956c43SDimitry Andric     setCount(BC.BreakCount + CondCount - LoopCount);
51259d1ed5bSDimitry Andric     RecordNextStmtCount = true;
51359d1ed5bSDimitry Andric   }
51459d1ed5bSDimitry Andric 
VisitForStmt__anon67ae45280111::ComputeRegionCounts51559d1ed5bSDimitry Andric   void VisitForStmt(const ForStmt *S) {
51659d1ed5bSDimitry Andric     RecordStmtCount(S);
51759d1ed5bSDimitry Andric     if (S->getInit())
51859d1ed5bSDimitry Andric       Visit(S->getInit());
51933956c43SDimitry Andric 
52033956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
52133956c43SDimitry Andric 
52259d1ed5bSDimitry Andric     BreakContinueStack.push_back(BreakContinue());
52359d1ed5bSDimitry Andric     // Visit the body region first. (This is basically the same as a while
52459d1ed5bSDimitry Andric     // loop; see further comments in VisitWhileStmt.)
52533956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
52633956c43SDimitry Andric     CountMap[S->getBody()] = BodyCount;
52759d1ed5bSDimitry Andric     Visit(S->getBody());
52833956c43SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
52933956c43SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
53059d1ed5bSDimitry Andric 
53159d1ed5bSDimitry Andric     // The increment is essentially part of the body but it needs to include
53259d1ed5bSDimitry Andric     // the count for all the continue statements.
53359d1ed5bSDimitry Andric     if (S->getInc()) {
53433956c43SDimitry Andric       uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
53533956c43SDimitry Andric       CountMap[S->getInc()] = IncCount;
53659d1ed5bSDimitry Andric       Visit(S->getInc());
53759d1ed5bSDimitry Andric     }
53859d1ed5bSDimitry Andric 
53959d1ed5bSDimitry Andric     // ...then go back and propagate counts through the condition.
54033956c43SDimitry Andric     uint64_t CondCount =
54133956c43SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
54259d1ed5bSDimitry Andric     if (S->getCond()) {
54333956c43SDimitry Andric       CountMap[S->getCond()] = CondCount;
54459d1ed5bSDimitry Andric       Visit(S->getCond());
54559d1ed5bSDimitry Andric     }
54633956c43SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
54759d1ed5bSDimitry Andric     RecordNextStmtCount = true;
54859d1ed5bSDimitry Andric   }
54959d1ed5bSDimitry Andric 
VisitCXXForRangeStmt__anon67ae45280111::ComputeRegionCounts55059d1ed5bSDimitry Andric   void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
55159d1ed5bSDimitry Andric     RecordStmtCount(S);
552*b5893f02SDimitry Andric     if (S->getInit())
553*b5893f02SDimitry Andric       Visit(S->getInit());
55433956c43SDimitry Andric     Visit(S->getLoopVarStmt());
55559d1ed5bSDimitry Andric     Visit(S->getRangeStmt());
556e7145dcbSDimitry Andric     Visit(S->getBeginStmt());
557e7145dcbSDimitry Andric     Visit(S->getEndStmt());
55833956c43SDimitry Andric 
55933956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
56059d1ed5bSDimitry Andric     BreakContinueStack.push_back(BreakContinue());
56159d1ed5bSDimitry Andric     // Visit the body region first. (This is basically the same as a while
56259d1ed5bSDimitry Andric     // loop; see further comments in VisitWhileStmt.)
56333956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
56433956c43SDimitry Andric     CountMap[S->getBody()] = BodyCount;
56559d1ed5bSDimitry Andric     Visit(S->getBody());
56633956c43SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
56733956c43SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
56859d1ed5bSDimitry Andric 
56959d1ed5bSDimitry Andric     // The increment is essentially part of the body but it needs to include
57059d1ed5bSDimitry Andric     // the count for all the continue statements.
57133956c43SDimitry Andric     uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
57233956c43SDimitry Andric     CountMap[S->getInc()] = IncCount;
57359d1ed5bSDimitry Andric     Visit(S->getInc());
57459d1ed5bSDimitry Andric 
57559d1ed5bSDimitry Andric     // ...then go back and propagate counts through the condition.
57633956c43SDimitry Andric     uint64_t CondCount =
57733956c43SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
57833956c43SDimitry Andric     CountMap[S->getCond()] = CondCount;
57959d1ed5bSDimitry Andric     Visit(S->getCond());
58033956c43SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
58159d1ed5bSDimitry Andric     RecordNextStmtCount = true;
58259d1ed5bSDimitry Andric   }
58359d1ed5bSDimitry Andric 
VisitObjCForCollectionStmt__anon67ae45280111::ComputeRegionCounts58459d1ed5bSDimitry Andric   void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
58559d1ed5bSDimitry Andric     RecordStmtCount(S);
58659d1ed5bSDimitry Andric     Visit(S->getElement());
58733956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
58859d1ed5bSDimitry Andric     BreakContinueStack.push_back(BreakContinue());
58933956c43SDimitry Andric     // Counter tracks the body of the loop.
59033956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
59133956c43SDimitry Andric     CountMap[S->getBody()] = BodyCount;
59259d1ed5bSDimitry Andric     Visit(S->getBody());
59333956c43SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
59459d1ed5bSDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
59533956c43SDimitry Andric 
59633956c43SDimitry Andric     setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount -
59733956c43SDimitry Andric              BodyCount);
59859d1ed5bSDimitry Andric     RecordNextStmtCount = true;
59959d1ed5bSDimitry Andric   }
60059d1ed5bSDimitry Andric 
VisitSwitchStmt__anon67ae45280111::ComputeRegionCounts60159d1ed5bSDimitry Andric   void VisitSwitchStmt(const SwitchStmt *S) {
60259d1ed5bSDimitry Andric     RecordStmtCount(S);
60344290647SDimitry Andric     if (S->getInit())
60444290647SDimitry Andric       Visit(S->getInit());
60559d1ed5bSDimitry Andric     Visit(S->getCond());
60633956c43SDimitry Andric     CurrentCount = 0;
60759d1ed5bSDimitry Andric     BreakContinueStack.push_back(BreakContinue());
60859d1ed5bSDimitry Andric     Visit(S->getBody());
60959d1ed5bSDimitry Andric     // If the switch is inside a loop, add the continue counts.
61059d1ed5bSDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
61159d1ed5bSDimitry Andric     if (!BreakContinueStack.empty())
61259d1ed5bSDimitry Andric       BreakContinueStack.back().ContinueCount += BC.ContinueCount;
61359d1ed5bSDimitry Andric     // Counter tracks the exit block of the switch.
61433956c43SDimitry Andric     setCount(PGO.getRegionCount(S));
61559d1ed5bSDimitry Andric     RecordNextStmtCount = true;
61659d1ed5bSDimitry Andric   }
61759d1ed5bSDimitry Andric 
VisitSwitchCase__anon67ae45280111::ComputeRegionCounts61833956c43SDimitry Andric   void VisitSwitchCase(const SwitchCase *S) {
61959d1ed5bSDimitry Andric     RecordNextStmtCount = false;
62059d1ed5bSDimitry Andric     // Counter for this particular case. This counts only jumps from the
62159d1ed5bSDimitry Andric     // switch header and does not include fallthrough from the case before
62259d1ed5bSDimitry Andric     // this one.
62333956c43SDimitry Andric     uint64_t CaseCount = PGO.getRegionCount(S);
62433956c43SDimitry Andric     setCount(CurrentCount + CaseCount);
62533956c43SDimitry Andric     // We need the count without fallthrough in the mapping, so it's more useful
62633956c43SDimitry Andric     // for branch probabilities.
62733956c43SDimitry Andric     CountMap[S] = CaseCount;
62859d1ed5bSDimitry Andric     RecordNextStmtCount = true;
62959d1ed5bSDimitry Andric     Visit(S->getSubStmt());
63059d1ed5bSDimitry Andric   }
63159d1ed5bSDimitry Andric 
VisitIfStmt__anon67ae45280111::ComputeRegionCounts63259d1ed5bSDimitry Andric   void VisitIfStmt(const IfStmt *S) {
63359d1ed5bSDimitry Andric     RecordStmtCount(S);
63433956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
63544290647SDimitry Andric     if (S->getInit())
63644290647SDimitry Andric       Visit(S->getInit());
63759d1ed5bSDimitry Andric     Visit(S->getCond());
63859d1ed5bSDimitry Andric 
63933956c43SDimitry Andric     // Counter tracks the "then" part of an if statement. The count for
64033956c43SDimitry Andric     // the "else" part, if it exists, will be calculated from this counter.
64133956c43SDimitry Andric     uint64_t ThenCount = setCount(PGO.getRegionCount(S));
64233956c43SDimitry Andric     CountMap[S->getThen()] = ThenCount;
64359d1ed5bSDimitry Andric     Visit(S->getThen());
64433956c43SDimitry Andric     uint64_t OutCount = CurrentCount;
64559d1ed5bSDimitry Andric 
64633956c43SDimitry Andric     uint64_t ElseCount = ParentCount - ThenCount;
64759d1ed5bSDimitry Andric     if (S->getElse()) {
64833956c43SDimitry Andric       setCount(ElseCount);
64933956c43SDimitry Andric       CountMap[S->getElse()] = ElseCount;
65059d1ed5bSDimitry Andric       Visit(S->getElse());
65133956c43SDimitry Andric       OutCount += CurrentCount;
65233956c43SDimitry Andric     } else
65333956c43SDimitry Andric       OutCount += ElseCount;
65433956c43SDimitry Andric     setCount(OutCount);
65559d1ed5bSDimitry Andric     RecordNextStmtCount = true;
65659d1ed5bSDimitry Andric   }
65759d1ed5bSDimitry Andric 
VisitCXXTryStmt__anon67ae45280111::ComputeRegionCounts65859d1ed5bSDimitry Andric   void VisitCXXTryStmt(const CXXTryStmt *S) {
65959d1ed5bSDimitry Andric     RecordStmtCount(S);
66059d1ed5bSDimitry Andric     Visit(S->getTryBlock());
66159d1ed5bSDimitry Andric     for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
66259d1ed5bSDimitry Andric       Visit(S->getHandler(I));
66359d1ed5bSDimitry Andric     // Counter tracks the continuation block of the try statement.
66433956c43SDimitry Andric     setCount(PGO.getRegionCount(S));
66559d1ed5bSDimitry Andric     RecordNextStmtCount = true;
66659d1ed5bSDimitry Andric   }
66759d1ed5bSDimitry Andric 
VisitCXXCatchStmt__anon67ae45280111::ComputeRegionCounts66859d1ed5bSDimitry Andric   void VisitCXXCatchStmt(const CXXCatchStmt *S) {
66959d1ed5bSDimitry Andric     RecordNextStmtCount = false;
67059d1ed5bSDimitry Andric     // Counter tracks the catch statement's handler block.
67133956c43SDimitry Andric     uint64_t CatchCount = setCount(PGO.getRegionCount(S));
67233956c43SDimitry Andric     CountMap[S] = CatchCount;
67359d1ed5bSDimitry Andric     Visit(S->getHandlerBlock());
67459d1ed5bSDimitry Andric   }
67559d1ed5bSDimitry Andric 
VisitAbstractConditionalOperator__anon67ae45280111::ComputeRegionCounts67633956c43SDimitry Andric   void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
67759d1ed5bSDimitry Andric     RecordStmtCount(E);
67833956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
67959d1ed5bSDimitry Andric     Visit(E->getCond());
68059d1ed5bSDimitry Andric 
68133956c43SDimitry Andric     // Counter tracks the "true" part of a conditional operator. The
68233956c43SDimitry Andric     // count in the "false" part will be calculated from this counter.
68333956c43SDimitry Andric     uint64_t TrueCount = setCount(PGO.getRegionCount(E));
68433956c43SDimitry Andric     CountMap[E->getTrueExpr()] = TrueCount;
68559d1ed5bSDimitry Andric     Visit(E->getTrueExpr());
68633956c43SDimitry Andric     uint64_t OutCount = CurrentCount;
68759d1ed5bSDimitry Andric 
68833956c43SDimitry Andric     uint64_t FalseCount = setCount(ParentCount - TrueCount);
68933956c43SDimitry Andric     CountMap[E->getFalseExpr()] = FalseCount;
69059d1ed5bSDimitry Andric     Visit(E->getFalseExpr());
69133956c43SDimitry Andric     OutCount += CurrentCount;
69259d1ed5bSDimitry Andric 
69333956c43SDimitry Andric     setCount(OutCount);
69459d1ed5bSDimitry Andric     RecordNextStmtCount = true;
69559d1ed5bSDimitry Andric   }
69659d1ed5bSDimitry Andric 
VisitBinLAnd__anon67ae45280111::ComputeRegionCounts69759d1ed5bSDimitry Andric   void VisitBinLAnd(const BinaryOperator *E) {
69859d1ed5bSDimitry Andric     RecordStmtCount(E);
69933956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
70059d1ed5bSDimitry Andric     Visit(E->getLHS());
70133956c43SDimitry Andric     // Counter tracks the right hand side of a logical and operator.
70233956c43SDimitry Andric     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
70333956c43SDimitry Andric     CountMap[E->getRHS()] = RHSCount;
70459d1ed5bSDimitry Andric     Visit(E->getRHS());
70533956c43SDimitry Andric     setCount(ParentCount + RHSCount - CurrentCount);
70659d1ed5bSDimitry Andric     RecordNextStmtCount = true;
70759d1ed5bSDimitry Andric   }
70859d1ed5bSDimitry Andric 
VisitBinLOr__anon67ae45280111::ComputeRegionCounts70959d1ed5bSDimitry Andric   void VisitBinLOr(const BinaryOperator *E) {
71059d1ed5bSDimitry Andric     RecordStmtCount(E);
71133956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
71259d1ed5bSDimitry Andric     Visit(E->getLHS());
71333956c43SDimitry Andric     // Counter tracks the right hand side of a logical or operator.
71433956c43SDimitry Andric     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
71533956c43SDimitry Andric     CountMap[E->getRHS()] = RHSCount;
71659d1ed5bSDimitry Andric     Visit(E->getRHS());
71733956c43SDimitry Andric     setCount(ParentCount + RHSCount - CurrentCount);
71859d1ed5bSDimitry Andric     RecordNextStmtCount = true;
71959d1ed5bSDimitry Andric   }
72059d1ed5bSDimitry Andric };
7210623d748SDimitry Andric } // end anonymous namespace
72259d1ed5bSDimitry Andric 
combine(HashType Type)72359d1ed5bSDimitry Andric void PGOHash::combine(HashType Type) {
72459d1ed5bSDimitry Andric   // Check that we never combine 0 and only have six bits.
72559d1ed5bSDimitry Andric   assert(Type && "Hash is invalid: unexpected type 0");
72659d1ed5bSDimitry Andric   assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
72759d1ed5bSDimitry Andric 
72859d1ed5bSDimitry Andric   // Pass through MD5 if enough work has built up.
72959d1ed5bSDimitry Andric   if (Count && Count % NumTypesPerWord == 0) {
73059d1ed5bSDimitry Andric     using namespace llvm::support;
73159d1ed5bSDimitry Andric     uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
73259d1ed5bSDimitry Andric     MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
73359d1ed5bSDimitry Andric     Working = 0;
73459d1ed5bSDimitry Andric   }
73559d1ed5bSDimitry Andric 
73659d1ed5bSDimitry Andric   // Accumulate the current type.
73759d1ed5bSDimitry Andric   ++Count;
73859d1ed5bSDimitry Andric   Working = Working << NumBitsPerType | Type;
73959d1ed5bSDimitry Andric }
74059d1ed5bSDimitry Andric 
finalize()74159d1ed5bSDimitry Andric uint64_t PGOHash::finalize() {
74259d1ed5bSDimitry Andric   // Use Working as the hash directly if we never used MD5.
74359d1ed5bSDimitry Andric   if (Count <= NumTypesPerWord)
74459d1ed5bSDimitry Andric     // No need to byte swap here, since none of the math was endian-dependent.
74559d1ed5bSDimitry Andric     // This number will be byte-swapped as required on endianness transitions,
74659d1ed5bSDimitry Andric     // so we will see the same value on the other side.
74759d1ed5bSDimitry Andric     return Working;
74859d1ed5bSDimitry Andric 
74959d1ed5bSDimitry Andric   // Check for remaining work in Working.
75059d1ed5bSDimitry Andric   if (Working)
75159d1ed5bSDimitry Andric     MD5.update(Working);
75259d1ed5bSDimitry Andric 
75359d1ed5bSDimitry Andric   // Finalize the MD5 and return the hash.
75459d1ed5bSDimitry Andric   llvm::MD5::MD5Result Result;
75559d1ed5bSDimitry Andric   MD5.final(Result);
75659d1ed5bSDimitry Andric   using namespace llvm::support;
75720e90f04SDimitry Andric   return Result.low();
75859d1ed5bSDimitry Andric }
75959d1ed5bSDimitry Andric 
assignRegionCounters(GlobalDecl GD,llvm::Function * Fn)7600623d748SDimitry Andric void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
7610623d748SDimitry Andric   const Decl *D = GD.getDecl();
762a580b014SDimitry Andric   if (!D->hasBody())
763a580b014SDimitry Andric     return;
764a580b014SDimitry Andric 
765e7145dcbSDimitry Andric   bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
76659d1ed5bSDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
76759d1ed5bSDimitry Andric   if (!InstrumentRegions && !PGOReader)
76859d1ed5bSDimitry Andric     return;
76959d1ed5bSDimitry Andric   if (D->isImplicit())
77059d1ed5bSDimitry Andric     return;
7710623d748SDimitry Andric   // Constructors and destructors may be represented by several functions in IR.
7720623d748SDimitry Andric   // If so, instrument only base variant, others are implemented by delegation
7730623d748SDimitry Andric   // to the base one, it would be counted twice otherwise.
77420e90f04SDimitry Andric   if (CGM.getTarget().getCXXABI().hasConstructorVariants()) {
77520e90f04SDimitry Andric     if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
77620e90f04SDimitry Andric       return;
77720e90f04SDimitry Andric 
77820e90f04SDimitry Andric     if (const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
77920e90f04SDimitry Andric       if (GD.getCtorType() != Ctor_Base &&
78020e90f04SDimitry Andric           CodeGenFunction::IsConstructorDelegationValid(CCD))
7810623d748SDimitry Andric         return;
7820623d748SDimitry Andric   }
78339d628a0SDimitry Andric   CGM.ClearUnusedCoverageMapping(D);
78459d1ed5bSDimitry Andric   setFuncName(Fn);
78559d1ed5bSDimitry Andric 
78659d1ed5bSDimitry Andric   mapRegionCounters(D);
78739d628a0SDimitry Andric   if (CGM.getCodeGenOpts().CoverageMapping)
78839d628a0SDimitry Andric     emitCounterRegionMapping(D);
78959d1ed5bSDimitry Andric   if (PGOReader) {
79059d1ed5bSDimitry Andric     SourceManager &SM = CGM.getContext().getSourceManager();
79159d1ed5bSDimitry Andric     loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
79259d1ed5bSDimitry Andric     computeRegionCounts(D);
79359d1ed5bSDimitry Andric     applyFunctionAttributes(PGOReader, Fn);
79459d1ed5bSDimitry Andric   }
79559d1ed5bSDimitry Andric }
79659d1ed5bSDimitry Andric 
mapRegionCounters(const Decl * D)79759d1ed5bSDimitry Andric void CodeGenPGO::mapRegionCounters(const Decl *D) {
7989a199699SDimitry Andric   // Use the latest hash version when inserting instrumentation, but use the
7999a199699SDimitry Andric   // version in the indexed profile if we're reading PGO data.
8009a199699SDimitry Andric   PGOHashVersion HashVersion = PGO_HASH_LATEST;
8019a199699SDimitry Andric   if (auto *PGOReader = CGM.getPGOReader())
8029a199699SDimitry Andric     HashVersion = getPGOHashVersion(PGOReader, CGM);
8039a199699SDimitry Andric 
80459d1ed5bSDimitry Andric   RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
8059a199699SDimitry Andric   MapRegionCounters Walker(HashVersion, *RegionCounterMap);
80659d1ed5bSDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
80759d1ed5bSDimitry Andric     Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
80859d1ed5bSDimitry Andric   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
80959d1ed5bSDimitry Andric     Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
81059d1ed5bSDimitry Andric   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
81159d1ed5bSDimitry Andric     Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
81259d1ed5bSDimitry Andric   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
81359d1ed5bSDimitry Andric     Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
81459d1ed5bSDimitry Andric   assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
81559d1ed5bSDimitry Andric   NumRegionCounters = Walker.NextCounter;
81659d1ed5bSDimitry Andric   FunctionHash = Walker.Hash.finalize();
81759d1ed5bSDimitry Andric }
81859d1ed5bSDimitry Andric 
skipRegionMappingForDecl(const Decl * D)819e7145dcbSDimitry Andric bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) {
82051690af2SDimitry Andric   if (!D->getBody())
821e7145dcbSDimitry Andric     return true;
822e7145dcbSDimitry Andric 
823e7145dcbSDimitry Andric   // Don't map the functions in system headers.
824e7145dcbSDimitry Andric   const auto &SM = CGM.getContext().getSourceManager();
825*b5893f02SDimitry Andric   auto Loc = D->getBody()->getBeginLoc();
826e7145dcbSDimitry Andric   return SM.isInSystemHeader(Loc);
827e7145dcbSDimitry Andric }
828e7145dcbSDimitry Andric 
emitCounterRegionMapping(const Decl * D)829e7145dcbSDimitry Andric void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
830e7145dcbSDimitry Andric   if (skipRegionMappingForDecl(D))
83139d628a0SDimitry Andric     return;
83239d628a0SDimitry Andric 
83339d628a0SDimitry Andric   std::string CoverageMapping;
83439d628a0SDimitry Andric   llvm::raw_string_ostream OS(CoverageMapping);
83539d628a0SDimitry Andric   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
83639d628a0SDimitry Andric                                 CGM.getContext().getSourceManager(),
83739d628a0SDimitry Andric                                 CGM.getLangOpts(), RegionCounterMap.get());
83839d628a0SDimitry Andric   MappingGen.emitCounterMapping(D, OS);
83939d628a0SDimitry Andric   OS.flush();
84039d628a0SDimitry Andric 
84139d628a0SDimitry Andric   if (CoverageMapping.empty())
84239d628a0SDimitry Andric     return;
84339d628a0SDimitry Andric 
84439d628a0SDimitry Andric   CGM.getCoverageMapping()->addFunctionMappingRecord(
84539d628a0SDimitry Andric       FuncNameVar, FuncName, FunctionHash, CoverageMapping);
84639d628a0SDimitry Andric }
84739d628a0SDimitry Andric 
84839d628a0SDimitry Andric void
emitEmptyCounterMapping(const Decl * D,StringRef Name,llvm::GlobalValue::LinkageTypes Linkage)84933956c43SDimitry Andric CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef Name,
85039d628a0SDimitry Andric                                     llvm::GlobalValue::LinkageTypes Linkage) {
851e7145dcbSDimitry Andric   if (skipRegionMappingForDecl(D))
85239d628a0SDimitry Andric     return;
85339d628a0SDimitry Andric 
85439d628a0SDimitry Andric   std::string CoverageMapping;
85539d628a0SDimitry Andric   llvm::raw_string_ostream OS(CoverageMapping);
85639d628a0SDimitry Andric   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
85739d628a0SDimitry Andric                                 CGM.getContext().getSourceManager(),
85839d628a0SDimitry Andric                                 CGM.getLangOpts());
85939d628a0SDimitry Andric   MappingGen.emitEmptyMapping(D, OS);
86039d628a0SDimitry Andric   OS.flush();
86139d628a0SDimitry Andric 
86239d628a0SDimitry Andric   if (CoverageMapping.empty())
86339d628a0SDimitry Andric     return;
86439d628a0SDimitry Andric 
86533956c43SDimitry Andric   setFuncName(Name, Linkage);
86639d628a0SDimitry Andric   CGM.getCoverageMapping()->addFunctionMappingRecord(
867444ed5c5SDimitry Andric       FuncNameVar, FuncName, FunctionHash, CoverageMapping, false);
86839d628a0SDimitry Andric }
86939d628a0SDimitry Andric 
computeRegionCounts(const Decl * D)87059d1ed5bSDimitry Andric void CodeGenPGO::computeRegionCounts(const Decl *D) {
87159d1ed5bSDimitry Andric   StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
87259d1ed5bSDimitry Andric   ComputeRegionCounts Walker(*StmtCountMap, *this);
87359d1ed5bSDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
87459d1ed5bSDimitry Andric     Walker.VisitFunctionDecl(FD);
87559d1ed5bSDimitry Andric   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
87659d1ed5bSDimitry Andric     Walker.VisitObjCMethodDecl(MD);
87759d1ed5bSDimitry Andric   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
87859d1ed5bSDimitry Andric     Walker.VisitBlockDecl(BD);
87959d1ed5bSDimitry Andric   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
88059d1ed5bSDimitry Andric     Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
88159d1ed5bSDimitry Andric }
88259d1ed5bSDimitry Andric 
88359d1ed5bSDimitry Andric void
applyFunctionAttributes(llvm::IndexedInstrProfReader * PGOReader,llvm::Function * Fn)88459d1ed5bSDimitry Andric CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
88559d1ed5bSDimitry Andric                                     llvm::Function *Fn) {
88659d1ed5bSDimitry Andric   if (!haveRegionCounts())
88759d1ed5bSDimitry Andric     return;
88859d1ed5bSDimitry Andric 
8890623d748SDimitry Andric   uint64_t FunctionCount = getRegionCount(nullptr);
89097bc6c73SDimitry Andric   Fn->setEntryCount(FunctionCount);
89159d1ed5bSDimitry Andric }
89259d1ed5bSDimitry Andric 
emitCounterIncrement(CGBuilderTy & Builder,const Stmt * S,llvm::Value * StepV)89320e90f04SDimitry Andric void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
89420e90f04SDimitry Andric                                       llvm::Value *StepV) {
895e7145dcbSDimitry Andric   if (!CGM.getCodeGenOpts().hasProfileClangInstr() || !RegionCounterMap)
89659d1ed5bSDimitry Andric     return;
8970623d748SDimitry Andric   if (!Builder.GetInsertBlock())
89839d628a0SDimitry Andric     return;
89933956c43SDimitry Andric 
90033956c43SDimitry Andric   unsigned Counter = (*RegionCounterMap)[S];
90139d628a0SDimitry Andric   auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
90220e90f04SDimitry Andric 
90320e90f04SDimitry Andric   llvm::Value *Args[] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
90439d628a0SDimitry Andric                          Builder.getInt64(FunctionHash),
90539d628a0SDimitry Andric                          Builder.getInt32(NumRegionCounters),
90620e90f04SDimitry Andric                          Builder.getInt32(Counter), StepV};
90720e90f04SDimitry Andric   if (!StepV)
90820e90f04SDimitry Andric     Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
90920e90f04SDimitry Andric                        makeArrayRef(Args, 4));
91020e90f04SDimitry Andric   else
91120e90f04SDimitry Andric     Builder.CreateCall(
91220e90f04SDimitry Andric         CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment_step),
91320e90f04SDimitry Andric         makeArrayRef(Args));
91459d1ed5bSDimitry Andric }
91559d1ed5bSDimitry Andric 
916e7145dcbSDimitry Andric // This method either inserts a call to the profile run-time during
917e7145dcbSDimitry Andric // instrumentation or puts profile data into metadata for PGO use.
valueProfile(CGBuilderTy & Builder,uint32_t ValueKind,llvm::Instruction * ValueSite,llvm::Value * ValuePtr)918e7145dcbSDimitry Andric void CodeGenPGO::valueProfile(CGBuilderTy &Builder, uint32_t ValueKind,
919e7145dcbSDimitry Andric     llvm::Instruction *ValueSite, llvm::Value *ValuePtr) {
920e7145dcbSDimitry Andric 
921e7145dcbSDimitry Andric   if (!EnableValueProfiling)
922e7145dcbSDimitry Andric     return;
923e7145dcbSDimitry Andric 
924e7145dcbSDimitry Andric   if (!ValuePtr || !ValueSite || !Builder.GetInsertBlock())
925e7145dcbSDimitry Andric     return;
926e7145dcbSDimitry Andric 
927e7145dcbSDimitry Andric   if (isa<llvm::Constant>(ValuePtr))
928e7145dcbSDimitry Andric     return;
929e7145dcbSDimitry Andric 
930e7145dcbSDimitry Andric   bool InstrumentValueSites = CGM.getCodeGenOpts().hasProfileClangInstr();
931e7145dcbSDimitry Andric   if (InstrumentValueSites && RegionCounterMap) {
932e7145dcbSDimitry Andric     auto BuilderInsertPoint = Builder.saveIP();
933e7145dcbSDimitry Andric     Builder.SetInsertPoint(ValueSite);
934e7145dcbSDimitry Andric     llvm::Value *Args[5] = {
935e7145dcbSDimitry Andric         llvm::ConstantExpr::getBitCast(FuncNameVar, Builder.getInt8PtrTy()),
936e7145dcbSDimitry Andric         Builder.getInt64(FunctionHash),
937e7145dcbSDimitry Andric         Builder.CreatePtrToInt(ValuePtr, Builder.getInt64Ty()),
938e7145dcbSDimitry Andric         Builder.getInt32(ValueKind),
939e7145dcbSDimitry Andric         Builder.getInt32(NumValueSites[ValueKind]++)
940e7145dcbSDimitry Andric     };
941e7145dcbSDimitry Andric     Builder.CreateCall(
942e7145dcbSDimitry Andric         CGM.getIntrinsic(llvm::Intrinsic::instrprof_value_profile), Args);
943e7145dcbSDimitry Andric     Builder.restoreIP(BuilderInsertPoint);
944e7145dcbSDimitry Andric     return;
945e7145dcbSDimitry Andric   }
946e7145dcbSDimitry Andric 
947e7145dcbSDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
948e7145dcbSDimitry Andric   if (PGOReader && haveRegionCounts()) {
949e7145dcbSDimitry Andric     // We record the top most called three functions at each call site.
950e7145dcbSDimitry Andric     // Profile metadata contains "VP" string identifying this metadata
951e7145dcbSDimitry Andric     // as value profiling data, then a uint32_t value for the value profiling
952e7145dcbSDimitry Andric     // kind, a uint64_t value for the total number of times the call is
953e7145dcbSDimitry Andric     // executed, followed by the function hash and execution count (uint64_t)
954e7145dcbSDimitry Andric     // pairs for each function.
955e7145dcbSDimitry Andric     if (NumValueSites[ValueKind] >= ProfRecord->getNumValueSites(ValueKind))
956e7145dcbSDimitry Andric       return;
957e7145dcbSDimitry Andric 
958e7145dcbSDimitry Andric     llvm::annotateValueSite(CGM.getModule(), *ValueSite, *ProfRecord,
959e7145dcbSDimitry Andric                             (llvm::InstrProfValueKind)ValueKind,
960e7145dcbSDimitry Andric                             NumValueSites[ValueKind]);
961e7145dcbSDimitry Andric 
962e7145dcbSDimitry Andric     NumValueSites[ValueKind]++;
963e7145dcbSDimitry Andric   }
964e7145dcbSDimitry Andric }
965e7145dcbSDimitry Andric 
loadRegionCounts(llvm::IndexedInstrProfReader * PGOReader,bool IsInMainFile)96659d1ed5bSDimitry Andric void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
96759d1ed5bSDimitry Andric                                   bool IsInMainFile) {
96859d1ed5bSDimitry Andric   CGM.getPGOStats().addVisited(IsInMainFile);
96939d628a0SDimitry Andric   RegionCounts.clear();
970e7145dcbSDimitry Andric   llvm::Expected<llvm::InstrProfRecord> RecordExpected =
971e7145dcbSDimitry Andric       PGOReader->getInstrProfRecord(FuncName, FunctionHash);
972e7145dcbSDimitry Andric   if (auto E = RecordExpected.takeError()) {
973e7145dcbSDimitry Andric     auto IPE = llvm::InstrProfError::take(std::move(E));
974e7145dcbSDimitry Andric     if (IPE == llvm::instrprof_error::unknown_function)
97559d1ed5bSDimitry Andric       CGM.getPGOStats().addMissing(IsInMainFile);
976e7145dcbSDimitry Andric     else if (IPE == llvm::instrprof_error::hash_mismatch)
97759d1ed5bSDimitry Andric       CGM.getPGOStats().addMismatched(IsInMainFile);
978e7145dcbSDimitry Andric     else if (IPE == llvm::instrprof_error::malformed)
97939d628a0SDimitry Andric       // TODO: Consider a more specific warning for this case.
98039d628a0SDimitry Andric       CGM.getPGOStats().addMismatched(IsInMainFile);
981e7145dcbSDimitry Andric     return;
98259d1ed5bSDimitry Andric   }
983e7145dcbSDimitry Andric   ProfRecord =
984e7145dcbSDimitry Andric       llvm::make_unique<llvm::InstrProfRecord>(std::move(RecordExpected.get()));
985e7145dcbSDimitry Andric   RegionCounts = ProfRecord->Counts;
98659d1ed5bSDimitry Andric }
98759d1ed5bSDimitry Andric 
9884ba319b5SDimitry Andric /// Calculate what to divide by to scale weights.
98959d1ed5bSDimitry Andric ///
99059d1ed5bSDimitry Andric /// Given the maximum weight, calculate a divisor that will scale all the
99159d1ed5bSDimitry Andric /// weights to strictly less than UINT32_MAX.
calculateWeightScale(uint64_t MaxWeight)99259d1ed5bSDimitry Andric static uint64_t calculateWeightScale(uint64_t MaxWeight) {
99359d1ed5bSDimitry Andric   return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
99459d1ed5bSDimitry Andric }
99559d1ed5bSDimitry Andric 
9964ba319b5SDimitry Andric /// Scale an individual branch weight (and add 1).
99759d1ed5bSDimitry Andric ///
99859d1ed5bSDimitry Andric /// Scale a 64-bit weight down to 32-bits using \c Scale.
99959d1ed5bSDimitry Andric ///
100059d1ed5bSDimitry Andric /// According to Laplace's Rule of Succession, it is better to compute the
100159d1ed5bSDimitry Andric /// weight based on the count plus 1, so universally add 1 to the value.
100259d1ed5bSDimitry Andric ///
100359d1ed5bSDimitry Andric /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
100459d1ed5bSDimitry Andric /// greater than \c Weight.
scaleBranchWeight(uint64_t Weight,uint64_t Scale)100559d1ed5bSDimitry Andric static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
100659d1ed5bSDimitry Andric   assert(Scale && "scale by 0?");
100759d1ed5bSDimitry Andric   uint64_t Scaled = Weight / Scale + 1;
100859d1ed5bSDimitry Andric   assert(Scaled <= UINT32_MAX && "overflow 32-bits");
100959d1ed5bSDimitry Andric   return Scaled;
101059d1ed5bSDimitry Andric }
101159d1ed5bSDimitry Andric 
createProfileWeights(uint64_t TrueCount,uint64_t FalseCount)101233956c43SDimitry Andric llvm::MDNode *CodeGenFunction::createProfileWeights(uint64_t TrueCount,
101359d1ed5bSDimitry Andric                                                     uint64_t FalseCount) {
101459d1ed5bSDimitry Andric   // Check for empty weights.
101559d1ed5bSDimitry Andric   if (!TrueCount && !FalseCount)
101659d1ed5bSDimitry Andric     return nullptr;
101759d1ed5bSDimitry Andric 
101859d1ed5bSDimitry Andric   // Calculate how to scale down to 32-bits.
101959d1ed5bSDimitry Andric   uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
102059d1ed5bSDimitry Andric 
102159d1ed5bSDimitry Andric   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
102259d1ed5bSDimitry Andric   return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
102359d1ed5bSDimitry Andric                                       scaleBranchWeight(FalseCount, Scale));
102459d1ed5bSDimitry Andric }
102559d1ed5bSDimitry Andric 
102633956c43SDimitry Andric llvm::MDNode *
createProfileWeights(ArrayRef<uint64_t> Weights)102733956c43SDimitry Andric CodeGenFunction::createProfileWeights(ArrayRef<uint64_t> Weights) {
102859d1ed5bSDimitry Andric   // We need at least two elements to create meaningful weights.
102959d1ed5bSDimitry Andric   if (Weights.size() < 2)
103059d1ed5bSDimitry Andric     return nullptr;
103159d1ed5bSDimitry Andric 
103259d1ed5bSDimitry Andric   // Check for empty weights.
103359d1ed5bSDimitry Andric   uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
103459d1ed5bSDimitry Andric   if (MaxWeight == 0)
103559d1ed5bSDimitry Andric     return nullptr;
103659d1ed5bSDimitry Andric 
103759d1ed5bSDimitry Andric   // Calculate how to scale down to 32-bits.
103859d1ed5bSDimitry Andric   uint64_t Scale = calculateWeightScale(MaxWeight);
103959d1ed5bSDimitry Andric 
104059d1ed5bSDimitry Andric   SmallVector<uint32_t, 16> ScaledWeights;
104159d1ed5bSDimitry Andric   ScaledWeights.reserve(Weights.size());
104259d1ed5bSDimitry Andric   for (uint64_t W : Weights)
104359d1ed5bSDimitry Andric     ScaledWeights.push_back(scaleBranchWeight(W, Scale));
104459d1ed5bSDimitry Andric 
104559d1ed5bSDimitry Andric   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
104659d1ed5bSDimitry Andric   return MDHelper.createBranchWeights(ScaledWeights);
104759d1ed5bSDimitry Andric }
104859d1ed5bSDimitry Andric 
createProfileWeightsForLoop(const Stmt * Cond,uint64_t LoopCount)104933956c43SDimitry Andric llvm::MDNode *CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond,
105033956c43SDimitry Andric                                                            uint64_t LoopCount) {
105133956c43SDimitry Andric   if (!PGO.haveRegionCounts())
105259d1ed5bSDimitry Andric     return nullptr;
105333956c43SDimitry Andric   Optional<uint64_t> CondCount = PGO.getStmtCount(Cond);
105433956c43SDimitry Andric   assert(CondCount.hasValue() && "missing expected loop condition count");
105533956c43SDimitry Andric   if (*CondCount == 0)
105659d1ed5bSDimitry Andric     return nullptr;
105733956c43SDimitry Andric   return createProfileWeights(LoopCount,
105833956c43SDimitry Andric                               std::max(*CondCount, LoopCount) - LoopCount);
105959d1ed5bSDimitry Andric }
1060