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 
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 
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 {
6159d1ed5bSDimitry Andric /// \brief 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:
8259d1ed5bSDimitry Andric   /// \brief 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 
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();
1369a199699SDimitry 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.
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 
1619a199699SDimitry 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.
16759d1ed5bSDimitry Andric   bool TraverseBlockExpr(BlockExpr *BE) { return true; }
16859d1ed5bSDimitry Andric   bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
16959d1ed5bSDimitry Andric   bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
17059d1ed5bSDimitry Andric 
17159d1ed5bSDimitry Andric   bool VisitDecl(const Decl *D) {
17259d1ed5bSDimitry Andric     switch (D->getKind()) {
17359d1ed5bSDimitry Andric     default:
17459d1ed5bSDimitry Andric       break;
17559d1ed5bSDimitry Andric     case Decl::Function:
17659d1ed5bSDimitry Andric     case Decl::CXXMethod:
17759d1ed5bSDimitry Andric     case Decl::CXXConstructor:
17859d1ed5bSDimitry Andric     case Decl::CXXDestructor:
17959d1ed5bSDimitry Andric     case Decl::CXXConversion:
18059d1ed5bSDimitry Andric     case Decl::ObjCMethod:
18159d1ed5bSDimitry Andric     case Decl::Block:
18259d1ed5bSDimitry Andric     case Decl::Captured:
18359d1ed5bSDimitry Andric       CounterMap[D->getBody()] = NextCounter++;
18459d1ed5bSDimitry Andric       break;
18559d1ed5bSDimitry Andric     }
18659d1ed5bSDimitry Andric     return true;
18759d1ed5bSDimitry Andric   }
18859d1ed5bSDimitry Andric 
1899a199699SDimitry Andric   /// If \p S gets a fresh counter, update the counter mappings. Return the
1909a199699SDimitry Andric   /// V1 hash of \p S.
1919a199699SDimitry Andric   PGOHash::HashType updateCounterMappings(Stmt *S) {
1929a199699SDimitry Andric     auto Type = getHashType(PGO_HASH_V1, S);
1939a199699SDimitry Andric     if (Type != PGOHash::None)
19459d1ed5bSDimitry Andric       CounterMap[S] = NextCounter++;
1959a199699SDimitry Andric     return Type;
1969a199699SDimitry Andric   }
1979a199699SDimitry Andric 
1989a199699SDimitry Andric   /// Include \p S in the function hash.
1999a199699SDimitry Andric   bool VisitStmt(Stmt *S) {
2009a199699SDimitry Andric     auto Type = updateCounterMappings(S);
2019a199699SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
2029a199699SDimitry Andric       Type = getHashType(Hash.getHashVersion(), S);
2039a199699SDimitry Andric     if (Type != PGOHash::None)
20459d1ed5bSDimitry Andric       Hash.combine(Type);
20559d1ed5bSDimitry Andric     return true;
20659d1ed5bSDimitry Andric   }
2079a199699SDimitry Andric 
2089a199699SDimitry Andric   bool TraverseIfStmt(IfStmt *If) {
2099a199699SDimitry Andric     // If we used the V1 hash, use the default traversal.
2109a199699SDimitry Andric     if (Hash.getHashVersion() == PGO_HASH_V1)
2119a199699SDimitry Andric       return Base::TraverseIfStmt(If);
2129a199699SDimitry Andric 
2139a199699SDimitry Andric     // Otherwise, keep track of which branch we're in while traversing.
2149a199699SDimitry Andric     VisitStmt(If);
2159a199699SDimitry Andric     for (Stmt *CS : If->children()) {
2169a199699SDimitry Andric       if (!CS)
2179a199699SDimitry Andric         continue;
2189a199699SDimitry Andric       if (CS == If->getThen())
2199a199699SDimitry Andric         Hash.combine(PGOHash::IfThenBranch);
2209a199699SDimitry Andric       else if (CS == If->getElse())
2219a199699SDimitry Andric         Hash.combine(PGOHash::IfElseBranch);
2229a199699SDimitry Andric       TraverseStmt(CS);
2239a199699SDimitry Andric     }
2249a199699SDimitry Andric     Hash.combine(PGOHash::EndOfScope);
2259a199699SDimitry Andric     return true;
2269a199699SDimitry Andric   }
2279a199699SDimitry Andric 
2289a199699SDimitry Andric // If the statement type \p N is nestable, and its nesting impacts profile
2299a199699SDimitry Andric // stability, define a custom traversal which tracks the end of the statement
2309a199699SDimitry Andric // in the hash (provided we're not using the V1 hash).
2319a199699SDimitry Andric #define DEFINE_NESTABLE_TRAVERSAL(N)                                           \
2329a199699SDimitry Andric   bool Traverse##N(N *S) {                                                     \
2339a199699SDimitry Andric     Base::Traverse##N(S);                                                      \
2349a199699SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)                                  \
2359a199699SDimitry Andric       Hash.combine(PGOHash::EndOfScope);                                       \
2369a199699SDimitry Andric     return true;                                                               \
2379a199699SDimitry Andric   }
2389a199699SDimitry Andric 
2399a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(WhileStmt)
2409a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(DoStmt)
2419a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(ForStmt)
2429a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXForRangeStmt)
2439a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(ObjCForCollectionStmt)
2449a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXTryStmt)
2459a199699SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXCatchStmt)
2469a199699SDimitry Andric 
2479a199699SDimitry Andric   /// Get version \p HashVersion of the PGO hash for \p S.
2489a199699SDimitry Andric   PGOHash::HashType getHashType(PGOHashVersion HashVersion, const Stmt *S) {
24959d1ed5bSDimitry Andric     switch (S->getStmtClass()) {
25059d1ed5bSDimitry Andric     default:
25159d1ed5bSDimitry Andric       break;
25259d1ed5bSDimitry Andric     case Stmt::LabelStmtClass:
25359d1ed5bSDimitry Andric       return PGOHash::LabelStmt;
25459d1ed5bSDimitry Andric     case Stmt::WhileStmtClass:
25559d1ed5bSDimitry Andric       return PGOHash::WhileStmt;
25659d1ed5bSDimitry Andric     case Stmt::DoStmtClass:
25759d1ed5bSDimitry Andric       return PGOHash::DoStmt;
25859d1ed5bSDimitry Andric     case Stmt::ForStmtClass:
25959d1ed5bSDimitry Andric       return PGOHash::ForStmt;
26059d1ed5bSDimitry Andric     case Stmt::CXXForRangeStmtClass:
26159d1ed5bSDimitry Andric       return PGOHash::CXXForRangeStmt;
26259d1ed5bSDimitry Andric     case Stmt::ObjCForCollectionStmtClass:
26359d1ed5bSDimitry Andric       return PGOHash::ObjCForCollectionStmt;
26459d1ed5bSDimitry Andric     case Stmt::SwitchStmtClass:
26559d1ed5bSDimitry Andric       return PGOHash::SwitchStmt;
26659d1ed5bSDimitry Andric     case Stmt::CaseStmtClass:
26759d1ed5bSDimitry Andric       return PGOHash::CaseStmt;
26859d1ed5bSDimitry Andric     case Stmt::DefaultStmtClass:
26959d1ed5bSDimitry Andric       return PGOHash::DefaultStmt;
27059d1ed5bSDimitry Andric     case Stmt::IfStmtClass:
27159d1ed5bSDimitry Andric       return PGOHash::IfStmt;
27259d1ed5bSDimitry Andric     case Stmt::CXXTryStmtClass:
27359d1ed5bSDimitry Andric       return PGOHash::CXXTryStmt;
27459d1ed5bSDimitry Andric     case Stmt::CXXCatchStmtClass:
27559d1ed5bSDimitry Andric       return PGOHash::CXXCatchStmt;
27659d1ed5bSDimitry Andric     case Stmt::ConditionalOperatorClass:
27759d1ed5bSDimitry Andric       return PGOHash::ConditionalOperator;
27859d1ed5bSDimitry Andric     case Stmt::BinaryConditionalOperatorClass:
27959d1ed5bSDimitry Andric       return PGOHash::BinaryConditionalOperator;
28059d1ed5bSDimitry Andric     case Stmt::BinaryOperatorClass: {
28159d1ed5bSDimitry Andric       const BinaryOperator *BO = cast<BinaryOperator>(S);
28259d1ed5bSDimitry Andric       if (BO->getOpcode() == BO_LAnd)
28359d1ed5bSDimitry Andric         return PGOHash::BinaryOperatorLAnd;
28459d1ed5bSDimitry Andric       if (BO->getOpcode() == BO_LOr)
28559d1ed5bSDimitry Andric         return PGOHash::BinaryOperatorLOr;
2869a199699SDimitry Andric       if (HashVersion == PGO_HASH_V2) {
2879a199699SDimitry Andric         switch (BO->getOpcode()) {
2889a199699SDimitry Andric         default:
2899a199699SDimitry Andric           break;
2909a199699SDimitry Andric         case BO_LT:
2919a199699SDimitry Andric           return PGOHash::BinaryOperatorLT;
2929a199699SDimitry Andric         case BO_GT:
2939a199699SDimitry Andric           return PGOHash::BinaryOperatorGT;
2949a199699SDimitry Andric         case BO_LE:
2959a199699SDimitry Andric           return PGOHash::BinaryOperatorLE;
2969a199699SDimitry Andric         case BO_GE:
2979a199699SDimitry Andric           return PGOHash::BinaryOperatorGE;
2989a199699SDimitry Andric         case BO_EQ:
2999a199699SDimitry Andric           return PGOHash::BinaryOperatorEQ;
3009a199699SDimitry Andric         case BO_NE:
3019a199699SDimitry Andric           return PGOHash::BinaryOperatorNE;
3029a199699SDimitry Andric         }
3039a199699SDimitry Andric       }
30459d1ed5bSDimitry Andric       break;
30559d1ed5bSDimitry Andric     }
30659d1ed5bSDimitry Andric     }
3079a199699SDimitry Andric 
3089a199699SDimitry Andric     if (HashVersion == PGO_HASH_V2) {
3099a199699SDimitry Andric       switch (S->getStmtClass()) {
3109a199699SDimitry Andric       default:
3119a199699SDimitry Andric         break;
3129a199699SDimitry Andric       case Stmt::GotoStmtClass:
3139a199699SDimitry Andric         return PGOHash::GotoStmt;
3149a199699SDimitry Andric       case Stmt::IndirectGotoStmtClass:
3159a199699SDimitry Andric         return PGOHash::IndirectGotoStmt;
3169a199699SDimitry Andric       case Stmt::BreakStmtClass:
3179a199699SDimitry Andric         return PGOHash::BreakStmt;
3189a199699SDimitry Andric       case Stmt::ContinueStmtClass:
3199a199699SDimitry Andric         return PGOHash::ContinueStmt;
3209a199699SDimitry Andric       case Stmt::ReturnStmtClass:
3219a199699SDimitry Andric         return PGOHash::ReturnStmt;
3229a199699SDimitry Andric       case Stmt::CXXThrowExprClass:
3239a199699SDimitry Andric         return PGOHash::ThrowExpr;
3249a199699SDimitry Andric       case Stmt::UnaryOperatorClass: {
3259a199699SDimitry Andric         const UnaryOperator *UO = cast<UnaryOperator>(S);
3269a199699SDimitry Andric         if (UO->getOpcode() == UO_LNot)
3279a199699SDimitry Andric           return PGOHash::UnaryOperatorLNot;
3289a199699SDimitry Andric         break;
3299a199699SDimitry Andric       }
3309a199699SDimitry Andric       }
3319a199699SDimitry Andric     }
3329a199699SDimitry Andric 
33359d1ed5bSDimitry Andric     return PGOHash::None;
33459d1ed5bSDimitry Andric   }
33559d1ed5bSDimitry Andric };
33659d1ed5bSDimitry Andric 
33759d1ed5bSDimitry Andric /// A StmtVisitor that propagates the raw counts through the AST and
33859d1ed5bSDimitry Andric /// records the count at statements where the value may change.
33959d1ed5bSDimitry Andric struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
34059d1ed5bSDimitry Andric   /// PGO state.
34159d1ed5bSDimitry Andric   CodeGenPGO &PGO;
34259d1ed5bSDimitry Andric 
34359d1ed5bSDimitry Andric   /// A flag that is set when the current count should be recorded on the
34459d1ed5bSDimitry Andric   /// next statement, such as at the exit of a loop.
34559d1ed5bSDimitry Andric   bool RecordNextStmtCount;
34659d1ed5bSDimitry Andric 
34733956c43SDimitry Andric   /// The count at the current location in the traversal.
34833956c43SDimitry Andric   uint64_t CurrentCount;
34933956c43SDimitry Andric 
35059d1ed5bSDimitry Andric   /// The map of statements to count values.
35159d1ed5bSDimitry Andric   llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
35259d1ed5bSDimitry Andric 
35359d1ed5bSDimitry Andric   /// BreakContinueStack - Keep counts of breaks and continues inside loops.
35459d1ed5bSDimitry Andric   struct BreakContinue {
35559d1ed5bSDimitry Andric     uint64_t BreakCount;
35659d1ed5bSDimitry Andric     uint64_t ContinueCount;
35759d1ed5bSDimitry Andric     BreakContinue() : BreakCount(0), ContinueCount(0) {}
35859d1ed5bSDimitry Andric   };
35959d1ed5bSDimitry Andric   SmallVector<BreakContinue, 8> BreakContinueStack;
36059d1ed5bSDimitry Andric 
36159d1ed5bSDimitry Andric   ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
36259d1ed5bSDimitry Andric                       CodeGenPGO &PGO)
36359d1ed5bSDimitry Andric       : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
36459d1ed5bSDimitry Andric 
36559d1ed5bSDimitry Andric   void RecordStmtCount(const Stmt *S) {
36659d1ed5bSDimitry Andric     if (RecordNextStmtCount) {
36733956c43SDimitry Andric       CountMap[S] = CurrentCount;
36859d1ed5bSDimitry Andric       RecordNextStmtCount = false;
36959d1ed5bSDimitry Andric     }
37059d1ed5bSDimitry Andric   }
37159d1ed5bSDimitry Andric 
37233956c43SDimitry Andric   /// Set and return the current count.
37333956c43SDimitry Andric   uint64_t setCount(uint64_t Count) {
37433956c43SDimitry Andric     CurrentCount = Count;
37533956c43SDimitry Andric     return Count;
37633956c43SDimitry Andric   }
37733956c43SDimitry Andric 
37859d1ed5bSDimitry Andric   void VisitStmt(const Stmt *S) {
37959d1ed5bSDimitry Andric     RecordStmtCount(S);
3803dac3a9bSDimitry Andric     for (const Stmt *Child : S->children())
3813dac3a9bSDimitry Andric       if (Child)
3823dac3a9bSDimitry Andric         this->Visit(Child);
38359d1ed5bSDimitry Andric   }
38459d1ed5bSDimitry Andric 
38559d1ed5bSDimitry Andric   void VisitFunctionDecl(const FunctionDecl *D) {
38659d1ed5bSDimitry Andric     // Counter tracks entry to the function body.
38733956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
38833956c43SDimitry Andric     CountMap[D->getBody()] = BodyCount;
38959d1ed5bSDimitry Andric     Visit(D->getBody());
39059d1ed5bSDimitry Andric   }
39159d1ed5bSDimitry Andric 
39259d1ed5bSDimitry Andric   // Skip lambda expressions. We visit these as FunctionDecls when we're
39359d1ed5bSDimitry Andric   // generating them and aren't interested in the body when generating a
39459d1ed5bSDimitry Andric   // parent context.
39559d1ed5bSDimitry Andric   void VisitLambdaExpr(const LambdaExpr *LE) {}
39659d1ed5bSDimitry Andric 
39759d1ed5bSDimitry Andric   void VisitCapturedDecl(const CapturedDecl *D) {
39859d1ed5bSDimitry Andric     // Counter tracks entry to the capture body.
39933956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
40033956c43SDimitry Andric     CountMap[D->getBody()] = BodyCount;
40159d1ed5bSDimitry Andric     Visit(D->getBody());
40259d1ed5bSDimitry Andric   }
40359d1ed5bSDimitry Andric 
40459d1ed5bSDimitry Andric   void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
40559d1ed5bSDimitry Andric     // Counter tracks entry to the method body.
40633956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
40733956c43SDimitry Andric     CountMap[D->getBody()] = BodyCount;
40859d1ed5bSDimitry Andric     Visit(D->getBody());
40959d1ed5bSDimitry Andric   }
41059d1ed5bSDimitry Andric 
41159d1ed5bSDimitry Andric   void VisitBlockDecl(const BlockDecl *D) {
41259d1ed5bSDimitry Andric     // Counter tracks entry to the block body.
41333956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
41433956c43SDimitry Andric     CountMap[D->getBody()] = BodyCount;
41559d1ed5bSDimitry Andric     Visit(D->getBody());
41659d1ed5bSDimitry Andric   }
41759d1ed5bSDimitry Andric 
41859d1ed5bSDimitry Andric   void VisitReturnStmt(const ReturnStmt *S) {
41959d1ed5bSDimitry Andric     RecordStmtCount(S);
42059d1ed5bSDimitry Andric     if (S->getRetValue())
42159d1ed5bSDimitry Andric       Visit(S->getRetValue());
42233956c43SDimitry Andric     CurrentCount = 0;
42333956c43SDimitry Andric     RecordNextStmtCount = true;
42433956c43SDimitry Andric   }
42533956c43SDimitry Andric 
42633956c43SDimitry Andric   void VisitCXXThrowExpr(const CXXThrowExpr *E) {
42733956c43SDimitry Andric     RecordStmtCount(E);
42833956c43SDimitry Andric     if (E->getSubExpr())
42933956c43SDimitry Andric       Visit(E->getSubExpr());
43033956c43SDimitry Andric     CurrentCount = 0;
43159d1ed5bSDimitry Andric     RecordNextStmtCount = true;
43259d1ed5bSDimitry Andric   }
43359d1ed5bSDimitry Andric 
43459d1ed5bSDimitry Andric   void VisitGotoStmt(const GotoStmt *S) {
43559d1ed5bSDimitry Andric     RecordStmtCount(S);
43633956c43SDimitry Andric     CurrentCount = 0;
43759d1ed5bSDimitry Andric     RecordNextStmtCount = true;
43859d1ed5bSDimitry Andric   }
43959d1ed5bSDimitry Andric 
44059d1ed5bSDimitry Andric   void VisitLabelStmt(const LabelStmt *S) {
44159d1ed5bSDimitry Andric     RecordNextStmtCount = false;
44259d1ed5bSDimitry Andric     // Counter tracks the block following the label.
44333956c43SDimitry Andric     uint64_t BlockCount = setCount(PGO.getRegionCount(S));
44433956c43SDimitry Andric     CountMap[S] = BlockCount;
44559d1ed5bSDimitry Andric     Visit(S->getSubStmt());
44659d1ed5bSDimitry Andric   }
44759d1ed5bSDimitry Andric 
44859d1ed5bSDimitry Andric   void VisitBreakStmt(const BreakStmt *S) {
44959d1ed5bSDimitry Andric     RecordStmtCount(S);
45059d1ed5bSDimitry Andric     assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
45133956c43SDimitry Andric     BreakContinueStack.back().BreakCount += CurrentCount;
45233956c43SDimitry Andric     CurrentCount = 0;
45359d1ed5bSDimitry Andric     RecordNextStmtCount = true;
45459d1ed5bSDimitry Andric   }
45559d1ed5bSDimitry Andric 
45659d1ed5bSDimitry Andric   void VisitContinueStmt(const ContinueStmt *S) {
45759d1ed5bSDimitry Andric     RecordStmtCount(S);
45859d1ed5bSDimitry Andric     assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
45933956c43SDimitry Andric     BreakContinueStack.back().ContinueCount += CurrentCount;
46033956c43SDimitry Andric     CurrentCount = 0;
46159d1ed5bSDimitry Andric     RecordNextStmtCount = true;
46259d1ed5bSDimitry Andric   }
46359d1ed5bSDimitry Andric 
46459d1ed5bSDimitry Andric   void VisitWhileStmt(const WhileStmt *S) {
46559d1ed5bSDimitry Andric     RecordStmtCount(S);
46633956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
46733956c43SDimitry Andric 
46859d1ed5bSDimitry Andric     BreakContinueStack.push_back(BreakContinue());
46959d1ed5bSDimitry Andric     // Visit the body region first so the break/continue adjustments can be
47059d1ed5bSDimitry Andric     // included when visiting the condition.
47133956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
47233956c43SDimitry Andric     CountMap[S->getBody()] = CurrentCount;
47359d1ed5bSDimitry Andric     Visit(S->getBody());
47433956c43SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
47559d1ed5bSDimitry Andric 
47659d1ed5bSDimitry Andric     // ...then go back and propagate counts through the condition. The count
47759d1ed5bSDimitry Andric     // at the start of the condition is the sum of the incoming edges,
47859d1ed5bSDimitry Andric     // the backedge from the end of the loop body, and the edges from
47959d1ed5bSDimitry Andric     // continue statements.
48059d1ed5bSDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
48133956c43SDimitry Andric     uint64_t CondCount =
48233956c43SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
48333956c43SDimitry Andric     CountMap[S->getCond()] = CondCount;
48459d1ed5bSDimitry Andric     Visit(S->getCond());
48533956c43SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
48659d1ed5bSDimitry Andric     RecordNextStmtCount = true;
48759d1ed5bSDimitry Andric   }
48859d1ed5bSDimitry Andric 
48959d1ed5bSDimitry Andric   void VisitDoStmt(const DoStmt *S) {
49059d1ed5bSDimitry Andric     RecordStmtCount(S);
49133956c43SDimitry Andric     uint64_t LoopCount = PGO.getRegionCount(S);
49233956c43SDimitry Andric 
49359d1ed5bSDimitry Andric     BreakContinueStack.push_back(BreakContinue());
49433956c43SDimitry Andric     // The count doesn't include the fallthrough from the parent scope. Add it.
49533956c43SDimitry Andric     uint64_t BodyCount = setCount(LoopCount + CurrentCount);
49633956c43SDimitry Andric     CountMap[S->getBody()] = BodyCount;
49759d1ed5bSDimitry Andric     Visit(S->getBody());
49833956c43SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
49959d1ed5bSDimitry Andric 
50059d1ed5bSDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
50159d1ed5bSDimitry Andric     // The count at the start of the condition is equal to the count at the
50233956c43SDimitry Andric     // end of the body, plus any continues.
50333956c43SDimitry Andric     uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount);
50433956c43SDimitry Andric     CountMap[S->getCond()] = CondCount;
50559d1ed5bSDimitry Andric     Visit(S->getCond());
50633956c43SDimitry Andric     setCount(BC.BreakCount + CondCount - LoopCount);
50759d1ed5bSDimitry Andric     RecordNextStmtCount = true;
50859d1ed5bSDimitry Andric   }
50959d1ed5bSDimitry Andric 
51059d1ed5bSDimitry Andric   void VisitForStmt(const ForStmt *S) {
51159d1ed5bSDimitry Andric     RecordStmtCount(S);
51259d1ed5bSDimitry Andric     if (S->getInit())
51359d1ed5bSDimitry Andric       Visit(S->getInit());
51433956c43SDimitry Andric 
51533956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
51633956c43SDimitry Andric 
51759d1ed5bSDimitry Andric     BreakContinueStack.push_back(BreakContinue());
51859d1ed5bSDimitry Andric     // Visit the body region first. (This is basically the same as a while
51959d1ed5bSDimitry Andric     // loop; see further comments in VisitWhileStmt.)
52033956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
52133956c43SDimitry Andric     CountMap[S->getBody()] = BodyCount;
52259d1ed5bSDimitry Andric     Visit(S->getBody());
52333956c43SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
52433956c43SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
52559d1ed5bSDimitry Andric 
52659d1ed5bSDimitry Andric     // The increment is essentially part of the body but it needs to include
52759d1ed5bSDimitry Andric     // the count for all the continue statements.
52859d1ed5bSDimitry Andric     if (S->getInc()) {
52933956c43SDimitry Andric       uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
53033956c43SDimitry Andric       CountMap[S->getInc()] = IncCount;
53159d1ed5bSDimitry Andric       Visit(S->getInc());
53259d1ed5bSDimitry Andric     }
53359d1ed5bSDimitry Andric 
53459d1ed5bSDimitry Andric     // ...then go back and propagate counts through the condition.
53533956c43SDimitry Andric     uint64_t CondCount =
53633956c43SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
53759d1ed5bSDimitry Andric     if (S->getCond()) {
53833956c43SDimitry Andric       CountMap[S->getCond()] = CondCount;
53959d1ed5bSDimitry Andric       Visit(S->getCond());
54059d1ed5bSDimitry Andric     }
54133956c43SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
54259d1ed5bSDimitry Andric     RecordNextStmtCount = true;
54359d1ed5bSDimitry Andric   }
54459d1ed5bSDimitry Andric 
54559d1ed5bSDimitry Andric   void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
54659d1ed5bSDimitry Andric     RecordStmtCount(S);
54733956c43SDimitry Andric     Visit(S->getLoopVarStmt());
54859d1ed5bSDimitry Andric     Visit(S->getRangeStmt());
549e7145dcbSDimitry Andric     Visit(S->getBeginStmt());
550e7145dcbSDimitry Andric     Visit(S->getEndStmt());
55133956c43SDimitry Andric 
55233956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
55359d1ed5bSDimitry Andric     BreakContinueStack.push_back(BreakContinue());
55459d1ed5bSDimitry Andric     // Visit the body region first. (This is basically the same as a while
55559d1ed5bSDimitry Andric     // loop; see further comments in VisitWhileStmt.)
55633956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
55733956c43SDimitry Andric     CountMap[S->getBody()] = BodyCount;
55859d1ed5bSDimitry Andric     Visit(S->getBody());
55933956c43SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
56033956c43SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
56159d1ed5bSDimitry Andric 
56259d1ed5bSDimitry Andric     // The increment is essentially part of the body but it needs to include
56359d1ed5bSDimitry Andric     // the count for all the continue statements.
56433956c43SDimitry Andric     uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
56533956c43SDimitry Andric     CountMap[S->getInc()] = IncCount;
56659d1ed5bSDimitry Andric     Visit(S->getInc());
56759d1ed5bSDimitry Andric 
56859d1ed5bSDimitry Andric     // ...then go back and propagate counts through the condition.
56933956c43SDimitry Andric     uint64_t CondCount =
57033956c43SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
57133956c43SDimitry Andric     CountMap[S->getCond()] = CondCount;
57259d1ed5bSDimitry Andric     Visit(S->getCond());
57333956c43SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
57459d1ed5bSDimitry Andric     RecordNextStmtCount = true;
57559d1ed5bSDimitry Andric   }
57659d1ed5bSDimitry Andric 
57759d1ed5bSDimitry Andric   void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
57859d1ed5bSDimitry Andric     RecordStmtCount(S);
57959d1ed5bSDimitry Andric     Visit(S->getElement());
58033956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
58159d1ed5bSDimitry Andric     BreakContinueStack.push_back(BreakContinue());
58233956c43SDimitry Andric     // Counter tracks the body of the loop.
58333956c43SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
58433956c43SDimitry Andric     CountMap[S->getBody()] = BodyCount;
58559d1ed5bSDimitry Andric     Visit(S->getBody());
58633956c43SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
58759d1ed5bSDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
58833956c43SDimitry Andric 
58933956c43SDimitry Andric     setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount -
59033956c43SDimitry Andric              BodyCount);
59159d1ed5bSDimitry Andric     RecordNextStmtCount = true;
59259d1ed5bSDimitry Andric   }
59359d1ed5bSDimitry Andric 
59459d1ed5bSDimitry Andric   void VisitSwitchStmt(const SwitchStmt *S) {
59559d1ed5bSDimitry Andric     RecordStmtCount(S);
59644290647SDimitry Andric     if (S->getInit())
59744290647SDimitry Andric       Visit(S->getInit());
59859d1ed5bSDimitry Andric     Visit(S->getCond());
59933956c43SDimitry Andric     CurrentCount = 0;
60059d1ed5bSDimitry Andric     BreakContinueStack.push_back(BreakContinue());
60159d1ed5bSDimitry Andric     Visit(S->getBody());
60259d1ed5bSDimitry Andric     // If the switch is inside a loop, add the continue counts.
60359d1ed5bSDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
60459d1ed5bSDimitry Andric     if (!BreakContinueStack.empty())
60559d1ed5bSDimitry Andric       BreakContinueStack.back().ContinueCount += BC.ContinueCount;
60659d1ed5bSDimitry Andric     // Counter tracks the exit block of the switch.
60733956c43SDimitry Andric     setCount(PGO.getRegionCount(S));
60859d1ed5bSDimitry Andric     RecordNextStmtCount = true;
60959d1ed5bSDimitry Andric   }
61059d1ed5bSDimitry Andric 
61133956c43SDimitry Andric   void VisitSwitchCase(const SwitchCase *S) {
61259d1ed5bSDimitry Andric     RecordNextStmtCount = false;
61359d1ed5bSDimitry Andric     // Counter for this particular case. This counts only jumps from the
61459d1ed5bSDimitry Andric     // switch header and does not include fallthrough from the case before
61559d1ed5bSDimitry Andric     // this one.
61633956c43SDimitry Andric     uint64_t CaseCount = PGO.getRegionCount(S);
61733956c43SDimitry Andric     setCount(CurrentCount + CaseCount);
61833956c43SDimitry Andric     // We need the count without fallthrough in the mapping, so it's more useful
61933956c43SDimitry Andric     // for branch probabilities.
62033956c43SDimitry Andric     CountMap[S] = CaseCount;
62159d1ed5bSDimitry Andric     RecordNextStmtCount = true;
62259d1ed5bSDimitry Andric     Visit(S->getSubStmt());
62359d1ed5bSDimitry Andric   }
62459d1ed5bSDimitry Andric 
62559d1ed5bSDimitry Andric   void VisitIfStmt(const IfStmt *S) {
62659d1ed5bSDimitry Andric     RecordStmtCount(S);
62733956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
62844290647SDimitry Andric     if (S->getInit())
62944290647SDimitry Andric       Visit(S->getInit());
63059d1ed5bSDimitry Andric     Visit(S->getCond());
63159d1ed5bSDimitry Andric 
63233956c43SDimitry Andric     // Counter tracks the "then" part of an if statement. The count for
63333956c43SDimitry Andric     // the "else" part, if it exists, will be calculated from this counter.
63433956c43SDimitry Andric     uint64_t ThenCount = setCount(PGO.getRegionCount(S));
63533956c43SDimitry Andric     CountMap[S->getThen()] = ThenCount;
63659d1ed5bSDimitry Andric     Visit(S->getThen());
63733956c43SDimitry Andric     uint64_t OutCount = CurrentCount;
63859d1ed5bSDimitry Andric 
63933956c43SDimitry Andric     uint64_t ElseCount = ParentCount - ThenCount;
64059d1ed5bSDimitry Andric     if (S->getElse()) {
64133956c43SDimitry Andric       setCount(ElseCount);
64233956c43SDimitry Andric       CountMap[S->getElse()] = ElseCount;
64359d1ed5bSDimitry Andric       Visit(S->getElse());
64433956c43SDimitry Andric       OutCount += CurrentCount;
64533956c43SDimitry Andric     } else
64633956c43SDimitry Andric       OutCount += ElseCount;
64733956c43SDimitry Andric     setCount(OutCount);
64859d1ed5bSDimitry Andric     RecordNextStmtCount = true;
64959d1ed5bSDimitry Andric   }
65059d1ed5bSDimitry Andric 
65159d1ed5bSDimitry Andric   void VisitCXXTryStmt(const CXXTryStmt *S) {
65259d1ed5bSDimitry Andric     RecordStmtCount(S);
65359d1ed5bSDimitry Andric     Visit(S->getTryBlock());
65459d1ed5bSDimitry Andric     for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
65559d1ed5bSDimitry Andric       Visit(S->getHandler(I));
65659d1ed5bSDimitry Andric     // Counter tracks the continuation block of the try statement.
65733956c43SDimitry Andric     setCount(PGO.getRegionCount(S));
65859d1ed5bSDimitry Andric     RecordNextStmtCount = true;
65959d1ed5bSDimitry Andric   }
66059d1ed5bSDimitry Andric 
66159d1ed5bSDimitry Andric   void VisitCXXCatchStmt(const CXXCatchStmt *S) {
66259d1ed5bSDimitry Andric     RecordNextStmtCount = false;
66359d1ed5bSDimitry Andric     // Counter tracks the catch statement's handler block.
66433956c43SDimitry Andric     uint64_t CatchCount = setCount(PGO.getRegionCount(S));
66533956c43SDimitry Andric     CountMap[S] = CatchCount;
66659d1ed5bSDimitry Andric     Visit(S->getHandlerBlock());
66759d1ed5bSDimitry Andric   }
66859d1ed5bSDimitry Andric 
66933956c43SDimitry Andric   void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
67059d1ed5bSDimitry Andric     RecordStmtCount(E);
67133956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
67259d1ed5bSDimitry Andric     Visit(E->getCond());
67359d1ed5bSDimitry Andric 
67433956c43SDimitry Andric     // Counter tracks the "true" part of a conditional operator. The
67533956c43SDimitry Andric     // count in the "false" part will be calculated from this counter.
67633956c43SDimitry Andric     uint64_t TrueCount = setCount(PGO.getRegionCount(E));
67733956c43SDimitry Andric     CountMap[E->getTrueExpr()] = TrueCount;
67859d1ed5bSDimitry Andric     Visit(E->getTrueExpr());
67933956c43SDimitry Andric     uint64_t OutCount = CurrentCount;
68059d1ed5bSDimitry Andric 
68133956c43SDimitry Andric     uint64_t FalseCount = setCount(ParentCount - TrueCount);
68233956c43SDimitry Andric     CountMap[E->getFalseExpr()] = FalseCount;
68359d1ed5bSDimitry Andric     Visit(E->getFalseExpr());
68433956c43SDimitry Andric     OutCount += CurrentCount;
68559d1ed5bSDimitry Andric 
68633956c43SDimitry Andric     setCount(OutCount);
68759d1ed5bSDimitry Andric     RecordNextStmtCount = true;
68859d1ed5bSDimitry Andric   }
68959d1ed5bSDimitry Andric 
69059d1ed5bSDimitry Andric   void VisitBinLAnd(const BinaryOperator *E) {
69159d1ed5bSDimitry Andric     RecordStmtCount(E);
69233956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
69359d1ed5bSDimitry Andric     Visit(E->getLHS());
69433956c43SDimitry Andric     // Counter tracks the right hand side of a logical and operator.
69533956c43SDimitry Andric     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
69633956c43SDimitry Andric     CountMap[E->getRHS()] = RHSCount;
69759d1ed5bSDimitry Andric     Visit(E->getRHS());
69833956c43SDimitry Andric     setCount(ParentCount + RHSCount - CurrentCount);
69959d1ed5bSDimitry Andric     RecordNextStmtCount = true;
70059d1ed5bSDimitry Andric   }
70159d1ed5bSDimitry Andric 
70259d1ed5bSDimitry Andric   void VisitBinLOr(const BinaryOperator *E) {
70359d1ed5bSDimitry Andric     RecordStmtCount(E);
70433956c43SDimitry Andric     uint64_t ParentCount = CurrentCount;
70559d1ed5bSDimitry Andric     Visit(E->getLHS());
70633956c43SDimitry Andric     // Counter tracks the right hand side of a logical or operator.
70733956c43SDimitry Andric     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
70833956c43SDimitry Andric     CountMap[E->getRHS()] = RHSCount;
70959d1ed5bSDimitry Andric     Visit(E->getRHS());
71033956c43SDimitry Andric     setCount(ParentCount + RHSCount - CurrentCount);
71159d1ed5bSDimitry Andric     RecordNextStmtCount = true;
71259d1ed5bSDimitry Andric   }
71359d1ed5bSDimitry Andric };
7140623d748SDimitry Andric } // end anonymous namespace
71559d1ed5bSDimitry Andric 
71659d1ed5bSDimitry Andric void PGOHash::combine(HashType Type) {
71759d1ed5bSDimitry Andric   // Check that we never combine 0 and only have six bits.
71859d1ed5bSDimitry Andric   assert(Type && "Hash is invalid: unexpected type 0");
71959d1ed5bSDimitry Andric   assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
72059d1ed5bSDimitry Andric 
72159d1ed5bSDimitry Andric   // Pass through MD5 if enough work has built up.
72259d1ed5bSDimitry Andric   if (Count && Count % NumTypesPerWord == 0) {
72359d1ed5bSDimitry Andric     using namespace llvm::support;
72459d1ed5bSDimitry Andric     uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
72559d1ed5bSDimitry Andric     MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
72659d1ed5bSDimitry Andric     Working = 0;
72759d1ed5bSDimitry Andric   }
72859d1ed5bSDimitry Andric 
72959d1ed5bSDimitry Andric   // Accumulate the current type.
73059d1ed5bSDimitry Andric   ++Count;
73159d1ed5bSDimitry Andric   Working = Working << NumBitsPerType | Type;
73259d1ed5bSDimitry Andric }
73359d1ed5bSDimitry Andric 
73459d1ed5bSDimitry Andric uint64_t PGOHash::finalize() {
73559d1ed5bSDimitry Andric   // Use Working as the hash directly if we never used MD5.
73659d1ed5bSDimitry Andric   if (Count <= NumTypesPerWord)
73759d1ed5bSDimitry Andric     // No need to byte swap here, since none of the math was endian-dependent.
73859d1ed5bSDimitry Andric     // This number will be byte-swapped as required on endianness transitions,
73959d1ed5bSDimitry Andric     // so we will see the same value on the other side.
74059d1ed5bSDimitry Andric     return Working;
74159d1ed5bSDimitry Andric 
74259d1ed5bSDimitry Andric   // Check for remaining work in Working.
74359d1ed5bSDimitry Andric   if (Working)
74459d1ed5bSDimitry Andric     MD5.update(Working);
74559d1ed5bSDimitry Andric 
74659d1ed5bSDimitry Andric   // Finalize the MD5 and return the hash.
74759d1ed5bSDimitry Andric   llvm::MD5::MD5Result Result;
74859d1ed5bSDimitry Andric   MD5.final(Result);
74959d1ed5bSDimitry Andric   using namespace llvm::support;
75020e90f04SDimitry Andric   return Result.low();
75159d1ed5bSDimitry Andric }
75259d1ed5bSDimitry Andric 
7530623d748SDimitry Andric void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
7540623d748SDimitry Andric   const Decl *D = GD.getDecl();
755a580b014SDimitry Andric   if (!D->hasBody())
756a580b014SDimitry Andric     return;
757a580b014SDimitry Andric 
758e7145dcbSDimitry Andric   bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
75959d1ed5bSDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
76059d1ed5bSDimitry Andric   if (!InstrumentRegions && !PGOReader)
76159d1ed5bSDimitry Andric     return;
76259d1ed5bSDimitry Andric   if (D->isImplicit())
76359d1ed5bSDimitry Andric     return;
7640623d748SDimitry Andric   // Constructors and destructors may be represented by several functions in IR.
7650623d748SDimitry Andric   // If so, instrument only base variant, others are implemented by delegation
7660623d748SDimitry Andric   // to the base one, it would be counted twice otherwise.
76720e90f04SDimitry Andric   if (CGM.getTarget().getCXXABI().hasConstructorVariants()) {
76820e90f04SDimitry Andric     if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
76920e90f04SDimitry Andric       return;
77020e90f04SDimitry Andric 
77120e90f04SDimitry Andric     if (const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
77220e90f04SDimitry Andric       if (GD.getCtorType() != Ctor_Base &&
77320e90f04SDimitry Andric           CodeGenFunction::IsConstructorDelegationValid(CCD))
7740623d748SDimitry Andric         return;
7750623d748SDimitry Andric   }
77639d628a0SDimitry Andric   CGM.ClearUnusedCoverageMapping(D);
77759d1ed5bSDimitry Andric   setFuncName(Fn);
77859d1ed5bSDimitry Andric 
77959d1ed5bSDimitry Andric   mapRegionCounters(D);
78039d628a0SDimitry Andric   if (CGM.getCodeGenOpts().CoverageMapping)
78139d628a0SDimitry Andric     emitCounterRegionMapping(D);
78259d1ed5bSDimitry Andric   if (PGOReader) {
78359d1ed5bSDimitry Andric     SourceManager &SM = CGM.getContext().getSourceManager();
78459d1ed5bSDimitry Andric     loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
78559d1ed5bSDimitry Andric     computeRegionCounts(D);
78659d1ed5bSDimitry Andric     applyFunctionAttributes(PGOReader, Fn);
78759d1ed5bSDimitry Andric   }
78859d1ed5bSDimitry Andric }
78959d1ed5bSDimitry Andric 
79059d1ed5bSDimitry Andric void CodeGenPGO::mapRegionCounters(const Decl *D) {
7919a199699SDimitry Andric   // Use the latest hash version when inserting instrumentation, but use the
7929a199699SDimitry Andric   // version in the indexed profile if we're reading PGO data.
7939a199699SDimitry Andric   PGOHashVersion HashVersion = PGO_HASH_LATEST;
7949a199699SDimitry Andric   if (auto *PGOReader = CGM.getPGOReader())
7959a199699SDimitry Andric     HashVersion = getPGOHashVersion(PGOReader, CGM);
7969a199699SDimitry Andric 
79759d1ed5bSDimitry Andric   RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
7989a199699SDimitry Andric   MapRegionCounters Walker(HashVersion, *RegionCounterMap);
79959d1ed5bSDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
80059d1ed5bSDimitry Andric     Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
80159d1ed5bSDimitry Andric   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
80259d1ed5bSDimitry Andric     Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
80359d1ed5bSDimitry Andric   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
80459d1ed5bSDimitry Andric     Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
80559d1ed5bSDimitry Andric   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
80659d1ed5bSDimitry Andric     Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
80759d1ed5bSDimitry Andric   assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
80859d1ed5bSDimitry Andric   NumRegionCounters = Walker.NextCounter;
80959d1ed5bSDimitry Andric   FunctionHash = Walker.Hash.finalize();
81059d1ed5bSDimitry Andric }
81159d1ed5bSDimitry Andric 
812e7145dcbSDimitry Andric bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) {
81351690af2SDimitry Andric   if (!D->getBody())
814e7145dcbSDimitry Andric     return true;
815e7145dcbSDimitry Andric 
816e7145dcbSDimitry Andric   // Don't map the functions in system headers.
817e7145dcbSDimitry Andric   const auto &SM = CGM.getContext().getSourceManager();
81839d628a0SDimitry Andric   auto Loc = D->getBody()->getLocStart();
819e7145dcbSDimitry Andric   return SM.isInSystemHeader(Loc);
820e7145dcbSDimitry Andric }
821e7145dcbSDimitry Andric 
822e7145dcbSDimitry Andric void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
823e7145dcbSDimitry Andric   if (skipRegionMappingForDecl(D))
82439d628a0SDimitry Andric     return;
82539d628a0SDimitry Andric 
82639d628a0SDimitry Andric   std::string CoverageMapping;
82739d628a0SDimitry Andric   llvm::raw_string_ostream OS(CoverageMapping);
82839d628a0SDimitry Andric   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
82939d628a0SDimitry Andric                                 CGM.getContext().getSourceManager(),
83039d628a0SDimitry Andric                                 CGM.getLangOpts(), RegionCounterMap.get());
83139d628a0SDimitry Andric   MappingGen.emitCounterMapping(D, OS);
83239d628a0SDimitry Andric   OS.flush();
83339d628a0SDimitry Andric 
83439d628a0SDimitry Andric   if (CoverageMapping.empty())
83539d628a0SDimitry Andric     return;
83639d628a0SDimitry Andric 
83739d628a0SDimitry Andric   CGM.getCoverageMapping()->addFunctionMappingRecord(
83839d628a0SDimitry Andric       FuncNameVar, FuncName, FunctionHash, CoverageMapping);
83939d628a0SDimitry Andric }
84039d628a0SDimitry Andric 
84139d628a0SDimitry Andric void
84233956c43SDimitry Andric CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef Name,
84339d628a0SDimitry Andric                                     llvm::GlobalValue::LinkageTypes Linkage) {
844e7145dcbSDimitry Andric   if (skipRegionMappingForDecl(D))
84539d628a0SDimitry Andric     return;
84639d628a0SDimitry Andric 
84739d628a0SDimitry Andric   std::string CoverageMapping;
84839d628a0SDimitry Andric   llvm::raw_string_ostream OS(CoverageMapping);
84939d628a0SDimitry Andric   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
85039d628a0SDimitry Andric                                 CGM.getContext().getSourceManager(),
85139d628a0SDimitry Andric                                 CGM.getLangOpts());
85239d628a0SDimitry Andric   MappingGen.emitEmptyMapping(D, OS);
85339d628a0SDimitry Andric   OS.flush();
85439d628a0SDimitry Andric 
85539d628a0SDimitry Andric   if (CoverageMapping.empty())
85639d628a0SDimitry Andric     return;
85739d628a0SDimitry Andric 
85833956c43SDimitry Andric   setFuncName(Name, Linkage);
85939d628a0SDimitry Andric   CGM.getCoverageMapping()->addFunctionMappingRecord(
860444ed5c5SDimitry Andric       FuncNameVar, FuncName, FunctionHash, CoverageMapping, false);
86139d628a0SDimitry Andric }
86239d628a0SDimitry Andric 
86359d1ed5bSDimitry Andric void CodeGenPGO::computeRegionCounts(const Decl *D) {
86459d1ed5bSDimitry Andric   StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
86559d1ed5bSDimitry Andric   ComputeRegionCounts Walker(*StmtCountMap, *this);
86659d1ed5bSDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
86759d1ed5bSDimitry Andric     Walker.VisitFunctionDecl(FD);
86859d1ed5bSDimitry Andric   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
86959d1ed5bSDimitry Andric     Walker.VisitObjCMethodDecl(MD);
87059d1ed5bSDimitry Andric   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
87159d1ed5bSDimitry Andric     Walker.VisitBlockDecl(BD);
87259d1ed5bSDimitry Andric   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
87359d1ed5bSDimitry Andric     Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
87459d1ed5bSDimitry Andric }
87559d1ed5bSDimitry Andric 
87659d1ed5bSDimitry Andric void
87759d1ed5bSDimitry Andric CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
87859d1ed5bSDimitry Andric                                     llvm::Function *Fn) {
87959d1ed5bSDimitry Andric   if (!haveRegionCounts())
88059d1ed5bSDimitry Andric     return;
88159d1ed5bSDimitry Andric 
8820623d748SDimitry Andric   uint64_t FunctionCount = getRegionCount(nullptr);
88397bc6c73SDimitry Andric   Fn->setEntryCount(FunctionCount);
88459d1ed5bSDimitry Andric }
88559d1ed5bSDimitry Andric 
88620e90f04SDimitry Andric void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
88720e90f04SDimitry Andric                                       llvm::Value *StepV) {
888e7145dcbSDimitry Andric   if (!CGM.getCodeGenOpts().hasProfileClangInstr() || !RegionCounterMap)
88959d1ed5bSDimitry Andric     return;
8900623d748SDimitry Andric   if (!Builder.GetInsertBlock())
89139d628a0SDimitry Andric     return;
89233956c43SDimitry Andric 
89333956c43SDimitry Andric   unsigned Counter = (*RegionCounterMap)[S];
89439d628a0SDimitry Andric   auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
89520e90f04SDimitry Andric 
89620e90f04SDimitry Andric   llvm::Value *Args[] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
89739d628a0SDimitry Andric                          Builder.getInt64(FunctionHash),
89839d628a0SDimitry Andric                          Builder.getInt32(NumRegionCounters),
89920e90f04SDimitry Andric                          Builder.getInt32(Counter), StepV};
90020e90f04SDimitry Andric   if (!StepV)
90120e90f04SDimitry Andric     Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
90220e90f04SDimitry Andric                        makeArrayRef(Args, 4));
90320e90f04SDimitry Andric   else
90420e90f04SDimitry Andric     Builder.CreateCall(
90520e90f04SDimitry Andric         CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment_step),
90620e90f04SDimitry Andric         makeArrayRef(Args));
90759d1ed5bSDimitry Andric }
90859d1ed5bSDimitry Andric 
909e7145dcbSDimitry Andric // This method either inserts a call to the profile run-time during
910e7145dcbSDimitry Andric // instrumentation or puts profile data into metadata for PGO use.
911e7145dcbSDimitry Andric void CodeGenPGO::valueProfile(CGBuilderTy &Builder, uint32_t ValueKind,
912e7145dcbSDimitry Andric     llvm::Instruction *ValueSite, llvm::Value *ValuePtr) {
913e7145dcbSDimitry Andric 
914e7145dcbSDimitry Andric   if (!EnableValueProfiling)
915e7145dcbSDimitry Andric     return;
916e7145dcbSDimitry Andric 
917e7145dcbSDimitry Andric   if (!ValuePtr || !ValueSite || !Builder.GetInsertBlock())
918e7145dcbSDimitry Andric     return;
919e7145dcbSDimitry Andric 
920e7145dcbSDimitry Andric   if (isa<llvm::Constant>(ValuePtr))
921e7145dcbSDimitry Andric     return;
922e7145dcbSDimitry Andric 
923e7145dcbSDimitry Andric   bool InstrumentValueSites = CGM.getCodeGenOpts().hasProfileClangInstr();
924e7145dcbSDimitry Andric   if (InstrumentValueSites && RegionCounterMap) {
925e7145dcbSDimitry Andric     auto BuilderInsertPoint = Builder.saveIP();
926e7145dcbSDimitry Andric     Builder.SetInsertPoint(ValueSite);
927e7145dcbSDimitry Andric     llvm::Value *Args[5] = {
928e7145dcbSDimitry Andric         llvm::ConstantExpr::getBitCast(FuncNameVar, Builder.getInt8PtrTy()),
929e7145dcbSDimitry Andric         Builder.getInt64(FunctionHash),
930e7145dcbSDimitry Andric         Builder.CreatePtrToInt(ValuePtr, Builder.getInt64Ty()),
931e7145dcbSDimitry Andric         Builder.getInt32(ValueKind),
932e7145dcbSDimitry Andric         Builder.getInt32(NumValueSites[ValueKind]++)
933e7145dcbSDimitry Andric     };
934e7145dcbSDimitry Andric     Builder.CreateCall(
935e7145dcbSDimitry Andric         CGM.getIntrinsic(llvm::Intrinsic::instrprof_value_profile), Args);
936e7145dcbSDimitry Andric     Builder.restoreIP(BuilderInsertPoint);
937e7145dcbSDimitry Andric     return;
938e7145dcbSDimitry Andric   }
939e7145dcbSDimitry Andric 
940e7145dcbSDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
941e7145dcbSDimitry Andric   if (PGOReader && haveRegionCounts()) {
942e7145dcbSDimitry Andric     // We record the top most called three functions at each call site.
943e7145dcbSDimitry Andric     // Profile metadata contains "VP" string identifying this metadata
944e7145dcbSDimitry Andric     // as value profiling data, then a uint32_t value for the value profiling
945e7145dcbSDimitry Andric     // kind, a uint64_t value for the total number of times the call is
946e7145dcbSDimitry Andric     // executed, followed by the function hash and execution count (uint64_t)
947e7145dcbSDimitry Andric     // pairs for each function.
948e7145dcbSDimitry Andric     if (NumValueSites[ValueKind] >= ProfRecord->getNumValueSites(ValueKind))
949e7145dcbSDimitry Andric       return;
950e7145dcbSDimitry Andric 
951e7145dcbSDimitry Andric     llvm::annotateValueSite(CGM.getModule(), *ValueSite, *ProfRecord,
952e7145dcbSDimitry Andric                             (llvm::InstrProfValueKind)ValueKind,
953e7145dcbSDimitry Andric                             NumValueSites[ValueKind]);
954e7145dcbSDimitry Andric 
955e7145dcbSDimitry Andric     NumValueSites[ValueKind]++;
956e7145dcbSDimitry Andric   }
957e7145dcbSDimitry Andric }
958e7145dcbSDimitry Andric 
95959d1ed5bSDimitry Andric void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
96059d1ed5bSDimitry Andric                                   bool IsInMainFile) {
96159d1ed5bSDimitry Andric   CGM.getPGOStats().addVisited(IsInMainFile);
96239d628a0SDimitry Andric   RegionCounts.clear();
963e7145dcbSDimitry Andric   llvm::Expected<llvm::InstrProfRecord> RecordExpected =
964e7145dcbSDimitry Andric       PGOReader->getInstrProfRecord(FuncName, FunctionHash);
965e7145dcbSDimitry Andric   if (auto E = RecordExpected.takeError()) {
966e7145dcbSDimitry Andric     auto IPE = llvm::InstrProfError::take(std::move(E));
967e7145dcbSDimitry Andric     if (IPE == llvm::instrprof_error::unknown_function)
96859d1ed5bSDimitry Andric       CGM.getPGOStats().addMissing(IsInMainFile);
969e7145dcbSDimitry Andric     else if (IPE == llvm::instrprof_error::hash_mismatch)
97059d1ed5bSDimitry Andric       CGM.getPGOStats().addMismatched(IsInMainFile);
971e7145dcbSDimitry Andric     else if (IPE == llvm::instrprof_error::malformed)
97239d628a0SDimitry Andric       // TODO: Consider a more specific warning for this case.
97339d628a0SDimitry Andric       CGM.getPGOStats().addMismatched(IsInMainFile);
974e7145dcbSDimitry Andric     return;
97559d1ed5bSDimitry Andric   }
976e7145dcbSDimitry Andric   ProfRecord =
977e7145dcbSDimitry Andric       llvm::make_unique<llvm::InstrProfRecord>(std::move(RecordExpected.get()));
978e7145dcbSDimitry Andric   RegionCounts = ProfRecord->Counts;
97959d1ed5bSDimitry Andric }
98059d1ed5bSDimitry Andric 
98159d1ed5bSDimitry Andric /// \brief Calculate what to divide by to scale weights.
98259d1ed5bSDimitry Andric ///
98359d1ed5bSDimitry Andric /// Given the maximum weight, calculate a divisor that will scale all the
98459d1ed5bSDimitry Andric /// weights to strictly less than UINT32_MAX.
98559d1ed5bSDimitry Andric static uint64_t calculateWeightScale(uint64_t MaxWeight) {
98659d1ed5bSDimitry Andric   return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
98759d1ed5bSDimitry Andric }
98859d1ed5bSDimitry Andric 
98959d1ed5bSDimitry Andric /// \brief Scale an individual branch weight (and add 1).
99059d1ed5bSDimitry Andric ///
99159d1ed5bSDimitry Andric /// Scale a 64-bit weight down to 32-bits using \c Scale.
99259d1ed5bSDimitry Andric ///
99359d1ed5bSDimitry Andric /// According to Laplace's Rule of Succession, it is better to compute the
99459d1ed5bSDimitry Andric /// weight based on the count plus 1, so universally add 1 to the value.
99559d1ed5bSDimitry Andric ///
99659d1ed5bSDimitry Andric /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
99759d1ed5bSDimitry Andric /// greater than \c Weight.
99859d1ed5bSDimitry Andric static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
99959d1ed5bSDimitry Andric   assert(Scale && "scale by 0?");
100059d1ed5bSDimitry Andric   uint64_t Scaled = Weight / Scale + 1;
100159d1ed5bSDimitry Andric   assert(Scaled <= UINT32_MAX && "overflow 32-bits");
100259d1ed5bSDimitry Andric   return Scaled;
100359d1ed5bSDimitry Andric }
100459d1ed5bSDimitry Andric 
100533956c43SDimitry Andric llvm::MDNode *CodeGenFunction::createProfileWeights(uint64_t TrueCount,
100659d1ed5bSDimitry Andric                                                     uint64_t FalseCount) {
100759d1ed5bSDimitry Andric   // Check for empty weights.
100859d1ed5bSDimitry Andric   if (!TrueCount && !FalseCount)
100959d1ed5bSDimitry Andric     return nullptr;
101059d1ed5bSDimitry Andric 
101159d1ed5bSDimitry Andric   // Calculate how to scale down to 32-bits.
101259d1ed5bSDimitry Andric   uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
101359d1ed5bSDimitry Andric 
101459d1ed5bSDimitry Andric   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
101559d1ed5bSDimitry Andric   return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
101659d1ed5bSDimitry Andric                                       scaleBranchWeight(FalseCount, Scale));
101759d1ed5bSDimitry Andric }
101859d1ed5bSDimitry Andric 
101933956c43SDimitry Andric llvm::MDNode *
102033956c43SDimitry Andric CodeGenFunction::createProfileWeights(ArrayRef<uint64_t> Weights) {
102159d1ed5bSDimitry Andric   // We need at least two elements to create meaningful weights.
102259d1ed5bSDimitry Andric   if (Weights.size() < 2)
102359d1ed5bSDimitry Andric     return nullptr;
102459d1ed5bSDimitry Andric 
102559d1ed5bSDimitry Andric   // Check for empty weights.
102659d1ed5bSDimitry Andric   uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
102759d1ed5bSDimitry Andric   if (MaxWeight == 0)
102859d1ed5bSDimitry Andric     return nullptr;
102959d1ed5bSDimitry Andric 
103059d1ed5bSDimitry Andric   // Calculate how to scale down to 32-bits.
103159d1ed5bSDimitry Andric   uint64_t Scale = calculateWeightScale(MaxWeight);
103259d1ed5bSDimitry Andric 
103359d1ed5bSDimitry Andric   SmallVector<uint32_t, 16> ScaledWeights;
103459d1ed5bSDimitry Andric   ScaledWeights.reserve(Weights.size());
103559d1ed5bSDimitry Andric   for (uint64_t W : Weights)
103659d1ed5bSDimitry Andric     ScaledWeights.push_back(scaleBranchWeight(W, Scale));
103759d1ed5bSDimitry Andric 
103859d1ed5bSDimitry Andric   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
103959d1ed5bSDimitry Andric   return MDHelper.createBranchWeights(ScaledWeights);
104059d1ed5bSDimitry Andric }
104159d1ed5bSDimitry Andric 
104233956c43SDimitry Andric llvm::MDNode *CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond,
104333956c43SDimitry Andric                                                            uint64_t LoopCount) {
104433956c43SDimitry Andric   if (!PGO.haveRegionCounts())
104559d1ed5bSDimitry Andric     return nullptr;
104633956c43SDimitry Andric   Optional<uint64_t> CondCount = PGO.getStmtCount(Cond);
104733956c43SDimitry Andric   assert(CondCount.hasValue() && "missing expected loop condition count");
104833956c43SDimitry Andric   if (*CondCount == 0)
104959d1ed5bSDimitry Andric     return nullptr;
105033956c43SDimitry Andric   return createProfileWeights(LoopCount,
105133956c43SDimitry Andric                               std::max(*CondCount, LoopCount) - LoopCount);
105259d1ed5bSDimitry Andric }
1053