1ef512b99SJustin Bogner //===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- C++ -*-===//
2ef512b99SJustin Bogner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ef512b99SJustin Bogner //
7ef512b99SJustin Bogner //===----------------------------------------------------------------------===//
8ef512b99SJustin Bogner //
9ef512b99SJustin Bogner // Instrumentation-based profile-guided optimization
10ef512b99SJustin Bogner //
11ef512b99SJustin Bogner //===----------------------------------------------------------------------===//
12ef512b99SJustin Bogner 
13ef512b99SJustin Bogner #include "CodeGenPGO.h"
14ef512b99SJustin Bogner #include "CodeGenFunction.h"
15ee02499aSAlex Lorenz #include "CoverageMappingGen.h"
16ef512b99SJustin Bogner #include "clang/AST/RecursiveASTVisitor.h"
17ef512b99SJustin Bogner #include "clang/AST/StmtVisitor.h"
18970ac605SJustin Bogner #include "llvm/IR/Intrinsics.h"
19ef512b99SJustin Bogner #include "llvm/IR/MDBuilder.h"
204c1a1d3cSReid Kleckner #include "llvm/Support/CommandLine.h"
214bc7731aSDuncan P. N. Exon Smith #include "llvm/Support/Endian.h"
22ef512b99SJustin Bogner #include "llvm/Support/FileSystem.h"
234bc7731aSDuncan P. N. Exon Smith #include "llvm/Support/MD5.h"
24ef512b99SJustin Bogner 
258065f0b9SZachary Turner static llvm::cl::opt<bool>
268065f0b9SZachary Turner     EnableValueProfiling("enable-value-profiling", llvm::cl::ZeroOrMore,
278065f0b9SZachary Turner                          llvm::cl::desc("Enable value profiling"),
288065f0b9SZachary Turner                          llvm::cl::Hidden, llvm::cl::init(false));
29518276a5SBetul Buyukkurt 
30ef512b99SJustin Bogner using namespace clang;
31ef512b99SJustin Bogner using namespace CodeGen;
32ef512b99SJustin Bogner 
33ee02499aSAlex Lorenz void CodeGenPGO::setFuncName(StringRef Name,
34ee02499aSAlex Lorenz                              llvm::GlobalValue::LinkageTypes Linkage) {
35a569e24aSXinliang David Li   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
36a569e24aSXinliang David Li   FuncName = llvm::getPGOFuncName(
37a569e24aSXinliang David Li       Name, Linkage, CGM.getCodeGenOpts().MainFileName,
38a569e24aSXinliang David Li       PGOReader ? PGOReader->getVersion() : llvm::IndexedInstrProf::Version);
39970ac605SJustin Bogner 
40970ac605SJustin Bogner   // If we're generating a profile, create a variable for the name.
419837ef56SRong Xu   if (CGM.getCodeGenOpts().hasProfileClangInstr())
422d7ec5a9SXinliang David Li     FuncNameVar = llvm::createPGOFuncNameVar(CGM.getModule(), Linkage, FuncName);
43da1ebedeSBob Wilson }
44da1ebedeSBob Wilson 
45ee02499aSAlex Lorenz void CodeGenPGO::setFuncName(llvm::Function *Fn) {
46ee02499aSAlex Lorenz   setFuncName(Fn->getName(), Fn->getLinkage());
47f932f542SRong Xu   // Create PGOFuncName meta data.
48f932f542SRong Xu   llvm::createPGOFuncNameMetadata(*Fn, FuncName);
49ee02499aSAlex Lorenz }
50ee02499aSAlex Lorenz 
516186971aSVedant Kumar /// The version of the PGO hash algorithm.
526186971aSVedant Kumar enum PGOHashVersion : unsigned {
536186971aSVedant Kumar   PGO_HASH_V1,
546186971aSVedant Kumar   PGO_HASH_V2,
55de02a75eSserge-sans-paille   PGO_HASH_V3,
566186971aSVedant Kumar 
576186971aSVedant Kumar   // Keep this set to the latest hash version.
58de02a75eSserge-sans-paille   PGO_HASH_LATEST = PGO_HASH_V3
596186971aSVedant Kumar };
606186971aSVedant Kumar 
61ef512b99SJustin Bogner namespace {
629fc8faf9SAdrian Prantl /// Stable hasher for PGO region counters.
634bc7731aSDuncan P. N. Exon Smith ///
644bc7731aSDuncan P. N. Exon Smith /// PGOHash produces a stable hash of a given function's control flow.
654bc7731aSDuncan P. N. Exon Smith ///
664bc7731aSDuncan P. N. Exon Smith /// Changing the output of this hash will invalidate all previously generated
674bc7731aSDuncan P. N. Exon Smith /// profiles -- i.e., don't do it.
684bc7731aSDuncan P. N. Exon Smith ///
694bc7731aSDuncan P. N. Exon Smith /// \note  When this hash does eventually change (years?), we still need to
704bc7731aSDuncan P. N. Exon Smith /// support old hashes.  We'll need to pull in the version number from the
714bc7731aSDuncan P. N. Exon Smith /// profile data format and use the matching hash function.
724bc7731aSDuncan P. N. Exon Smith class PGOHash {
734bc7731aSDuncan P. N. Exon Smith   uint64_t Working;
744bc7731aSDuncan P. N. Exon Smith   unsigned Count;
756186971aSVedant Kumar   PGOHashVersion HashVersion;
764bc7731aSDuncan P. N. Exon Smith   llvm::MD5 MD5;
774bc7731aSDuncan P. N. Exon Smith 
784bc7731aSDuncan P. N. Exon Smith   static const int NumBitsPerType = 6;
794bc7731aSDuncan P. N. Exon Smith   static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
804bc7731aSDuncan P. N. Exon Smith   static const unsigned TooBig = 1u << NumBitsPerType;
814bc7731aSDuncan P. N. Exon Smith 
824bc7731aSDuncan P. N. Exon Smith public:
839fc8faf9SAdrian Prantl   /// Hash values for AST nodes.
844bc7731aSDuncan P. N. Exon Smith   ///
854bc7731aSDuncan P. N. Exon Smith   /// Distinct values for AST nodes that have region counters attached.
864bc7731aSDuncan P. N. Exon Smith   ///
874bc7731aSDuncan P. N. Exon Smith   /// These values must be stable.  All new members must be added at the end,
884bc7731aSDuncan P. N. Exon Smith   /// and no members should be removed.  Changing the enumeration value for an
894bc7731aSDuncan P. N. Exon Smith   /// AST node will affect the hash of every function that contains that node.
904bc7731aSDuncan P. N. Exon Smith   enum HashType : unsigned char {
914bc7731aSDuncan P. N. Exon Smith     None = 0,
924bc7731aSDuncan P. N. Exon Smith     LabelStmt = 1,
934bc7731aSDuncan P. N. Exon Smith     WhileStmt,
944bc7731aSDuncan P. N. Exon Smith     DoStmt,
954bc7731aSDuncan P. N. Exon Smith     ForStmt,
964bc7731aSDuncan P. N. Exon Smith     CXXForRangeStmt,
974bc7731aSDuncan P. N. Exon Smith     ObjCForCollectionStmt,
984bc7731aSDuncan P. N. Exon Smith     SwitchStmt,
994bc7731aSDuncan P. N. Exon Smith     CaseStmt,
1004bc7731aSDuncan P. N. Exon Smith     DefaultStmt,
1014bc7731aSDuncan P. N. Exon Smith     IfStmt,
1024bc7731aSDuncan P. N. Exon Smith     CXXTryStmt,
1034bc7731aSDuncan P. N. Exon Smith     CXXCatchStmt,
1044bc7731aSDuncan P. N. Exon Smith     ConditionalOperator,
1054bc7731aSDuncan P. N. Exon Smith     BinaryOperatorLAnd,
1064bc7731aSDuncan P. N. Exon Smith     BinaryOperatorLOr,
1074bc7731aSDuncan P. N. Exon Smith     BinaryConditionalOperator,
1086186971aSVedant Kumar     // The preceding values are available with PGO_HASH_V1.
1096186971aSVedant Kumar 
1106186971aSVedant Kumar     EndOfScope,
1116186971aSVedant Kumar     IfThenBranch,
1126186971aSVedant Kumar     IfElseBranch,
1136186971aSVedant Kumar     GotoStmt,
1146186971aSVedant Kumar     IndirectGotoStmt,
1156186971aSVedant Kumar     BreakStmt,
1166186971aSVedant Kumar     ContinueStmt,
1176186971aSVedant Kumar     ReturnStmt,
1186186971aSVedant Kumar     ThrowExpr,
1196186971aSVedant Kumar     UnaryOperatorLNot,
1206186971aSVedant Kumar     BinaryOperatorLT,
1216186971aSVedant Kumar     BinaryOperatorGT,
1226186971aSVedant Kumar     BinaryOperatorLE,
1236186971aSVedant Kumar     BinaryOperatorGE,
1246186971aSVedant Kumar     BinaryOperatorEQ,
1256186971aSVedant Kumar     BinaryOperatorNE,
126de02a75eSserge-sans-paille     // The preceding values are available since PGO_HASH_V2.
1274bc7731aSDuncan P. N. Exon Smith 
1284bc7731aSDuncan P. N. Exon Smith     // Keep this last.  It's for the static assert that follows.
1294bc7731aSDuncan P. N. Exon Smith     LastHashType
1304bc7731aSDuncan P. N. Exon Smith   };
1314bc7731aSDuncan P. N. Exon Smith   static_assert(LastHashType <= TooBig, "Too many types in HashType");
1324bc7731aSDuncan P. N. Exon Smith 
1336186971aSVedant Kumar   PGOHash(PGOHashVersion HashVersion)
1346186971aSVedant Kumar       : Working(0), Count(0), HashVersion(HashVersion), MD5() {}
1354bc7731aSDuncan P. N. Exon Smith   void combine(HashType Type);
1364bc7731aSDuncan P. N. Exon Smith   uint64_t finalize();
1376186971aSVedant Kumar   PGOHashVersion getHashVersion() const { return HashVersion; }
1384bc7731aSDuncan P. N. Exon Smith };
1394bc7731aSDuncan P. N. Exon Smith const int PGOHash::NumBitsPerType;
1404bc7731aSDuncan P. N. Exon Smith const unsigned PGOHash::NumTypesPerWord;
1414bc7731aSDuncan P. N. Exon Smith const unsigned PGOHash::TooBig;
1424bc7731aSDuncan P. N. Exon Smith 
1436186971aSVedant Kumar /// Get the PGO hash version used in the given indexed profile.
1446186971aSVedant Kumar static PGOHashVersion getPGOHashVersion(llvm::IndexedInstrProfReader *PGOReader,
1456186971aSVedant Kumar                                         CodeGenModule &CGM) {
1466186971aSVedant Kumar   if (PGOReader->getVersion() <= 4)
1476186971aSVedant Kumar     return PGO_HASH_V1;
148de02a75eSserge-sans-paille   if (PGOReader->getVersion() <= 5)
1496186971aSVedant Kumar     return PGO_HASH_V2;
150de02a75eSserge-sans-paille   return PGO_HASH_V3;
1516186971aSVedant Kumar }
1526186971aSVedant Kumar 
153d8931425SBob Wilson /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
154d8931425SBob Wilson struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
1556186971aSVedant Kumar   using Base = RecursiveASTVisitor<MapRegionCounters>;
1566186971aSVedant Kumar 
157ef512b99SJustin Bogner   /// The next counter value to assign.
158ef512b99SJustin Bogner   unsigned NextCounter;
1594bc7731aSDuncan P. N. Exon Smith   /// The function hash.
1604bc7731aSDuncan P. N. Exon Smith   PGOHash Hash;
161ef512b99SJustin Bogner   /// The map of statements to counters.
1623586be72SDuncan P. N. Exon Smith   llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
1639f2967bcSAlan Phipps   /// The profile version.
1649f2967bcSAlan Phipps   uint64_t ProfileVersion;
165ef512b99SJustin Bogner 
1669f2967bcSAlan Phipps   MapRegionCounters(PGOHashVersion HashVersion, uint64_t ProfileVersion,
1676186971aSVedant Kumar                     llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
1689f2967bcSAlan Phipps       : NextCounter(0), Hash(HashVersion), CounterMap(CounterMap),
1699f2967bcSAlan Phipps         ProfileVersion(ProfileVersion) {}
170ef512b99SJustin Bogner 
171191ec63bSJustin Bogner   // Blocks and lambdas are handled as separate functions, so we need not
172191ec63bSJustin Bogner   // traverse them in the parent context.
173191ec63bSJustin Bogner   bool TraverseBlockExpr(BlockExpr *BE) { return true; }
174e60151c9SSam McCall   bool TraverseLambdaExpr(LambdaExpr *LE) {
175e60151c9SSam McCall     // Traverse the captures, but not the body.
1768dc7b982SMark de Wever     for (auto C : zip(LE->captures(), LE->capture_inits()))
177e60151c9SSam McCall       TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
178e60151c9SSam McCall     return true;
179e60151c9SSam McCall   }
18081ab90f7SJustin Bogner   bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
181ef512b99SJustin Bogner 
182d8931425SBob Wilson   bool VisitDecl(const Decl *D) {
183d8931425SBob Wilson     switch (D->getKind()) {
184d8931425SBob Wilson     default:
185d8931425SBob Wilson       break;
186d8931425SBob Wilson     case Decl::Function:
187d8931425SBob Wilson     case Decl::CXXMethod:
188d8931425SBob Wilson     case Decl::CXXConstructor:
189d8931425SBob Wilson     case Decl::CXXDestructor:
190d8931425SBob Wilson     case Decl::CXXConversion:
191d8931425SBob Wilson     case Decl::ObjCMethod:
192d8931425SBob Wilson     case Decl::Block:
19381ab90f7SJustin Bogner     case Decl::Captured:
1944a2f5ae8SDuncan P. N. Exon Smith       CounterMap[D->getBody()] = NextCounter++;
195d8931425SBob Wilson       break;
196ef512b99SJustin Bogner     }
197d8931425SBob Wilson     return true;
1985ec8fe19SBob Wilson   }
199d8931425SBob Wilson 
2006186971aSVedant Kumar   /// If \p S gets a fresh counter, update the counter mappings. Return the
2016186971aSVedant Kumar   /// V1 hash of \p S.
2026186971aSVedant Kumar   PGOHash::HashType updateCounterMappings(Stmt *S) {
2036186971aSVedant Kumar     auto Type = getHashType(PGO_HASH_V1, S);
2046186971aSVedant Kumar     if (Type != PGOHash::None)
2054bc7731aSDuncan P. N. Exon Smith       CounterMap[S] = NextCounter++;
2066186971aSVedant Kumar     return Type;
2076186971aSVedant Kumar   }
2086186971aSVedant Kumar 
2099f2967bcSAlan Phipps   /// The RHS of all logical operators gets a fresh counter in order to count
2109f2967bcSAlan Phipps   /// how many times the RHS evaluates to true or false, depending on the
2119f2967bcSAlan Phipps   /// semantics of the operator. This is only valid for ">= v7" of the profile
2129f2967bcSAlan Phipps   /// version so that we facilitate backward compatibility.
2139f2967bcSAlan Phipps   bool VisitBinaryOperator(BinaryOperator *S) {
2149f2967bcSAlan Phipps     if (ProfileVersion >= llvm::IndexedInstrProf::Version7)
2159f2967bcSAlan Phipps       if (S->isLogicalOp() &&
2169f2967bcSAlan Phipps           CodeGenFunction::isInstrumentedCondition(S->getRHS()))
2179f2967bcSAlan Phipps         CounterMap[S->getRHS()] = NextCounter++;
2189f2967bcSAlan Phipps     return Base::VisitBinaryOperator(S);
2199f2967bcSAlan Phipps   }
2209f2967bcSAlan Phipps 
2216186971aSVedant Kumar   /// Include \p S in the function hash.
2226186971aSVedant Kumar   bool VisitStmt(Stmt *S) {
2236186971aSVedant Kumar     auto Type = updateCounterMappings(S);
2246186971aSVedant Kumar     if (Hash.getHashVersion() != PGO_HASH_V1)
2256186971aSVedant Kumar       Type = getHashType(Hash.getHashVersion(), S);
2266186971aSVedant Kumar     if (Type != PGOHash::None)
2274bc7731aSDuncan P. N. Exon Smith       Hash.combine(Type);
2284bc7731aSDuncan P. N. Exon Smith     return true;
2294bc7731aSDuncan P. N. Exon Smith   }
2306186971aSVedant Kumar 
2316186971aSVedant Kumar   bool TraverseIfStmt(IfStmt *If) {
2326186971aSVedant Kumar     // If we used the V1 hash, use the default traversal.
2336186971aSVedant Kumar     if (Hash.getHashVersion() == PGO_HASH_V1)
2346186971aSVedant Kumar       return Base::TraverseIfStmt(If);
2356186971aSVedant Kumar 
2366186971aSVedant Kumar     // Otherwise, keep track of which branch we're in while traversing.
2376186971aSVedant Kumar     VisitStmt(If);
2386186971aSVedant Kumar     for (Stmt *CS : If->children()) {
2396186971aSVedant Kumar       if (!CS)
2406186971aSVedant Kumar         continue;
2416186971aSVedant Kumar       if (CS == If->getThen())
2426186971aSVedant Kumar         Hash.combine(PGOHash::IfThenBranch);
2436186971aSVedant Kumar       else if (CS == If->getElse())
2446186971aSVedant Kumar         Hash.combine(PGOHash::IfElseBranch);
2456186971aSVedant Kumar       TraverseStmt(CS);
2466186971aSVedant Kumar     }
2476186971aSVedant Kumar     Hash.combine(PGOHash::EndOfScope);
2486186971aSVedant Kumar     return true;
2496186971aSVedant Kumar   }
2506186971aSVedant Kumar 
2516186971aSVedant Kumar // If the statement type \p N is nestable, and its nesting impacts profile
2526186971aSVedant Kumar // stability, define a custom traversal which tracks the end of the statement
2536186971aSVedant Kumar // in the hash (provided we're not using the V1 hash).
2546186971aSVedant Kumar #define DEFINE_NESTABLE_TRAVERSAL(N)                                           \
2556186971aSVedant Kumar   bool Traverse##N(N *S) {                                                     \
2566186971aSVedant Kumar     Base::Traverse##N(S);                                                      \
2576186971aSVedant Kumar     if (Hash.getHashVersion() != PGO_HASH_V1)                                  \
2586186971aSVedant Kumar       Hash.combine(PGOHash::EndOfScope);                                       \
2596186971aSVedant Kumar     return true;                                                               \
2606186971aSVedant Kumar   }
2616186971aSVedant Kumar 
2626186971aSVedant Kumar   DEFINE_NESTABLE_TRAVERSAL(WhileStmt)
2636186971aSVedant Kumar   DEFINE_NESTABLE_TRAVERSAL(DoStmt)
2646186971aSVedant Kumar   DEFINE_NESTABLE_TRAVERSAL(ForStmt)
2656186971aSVedant Kumar   DEFINE_NESTABLE_TRAVERSAL(CXXForRangeStmt)
2666186971aSVedant Kumar   DEFINE_NESTABLE_TRAVERSAL(ObjCForCollectionStmt)
2676186971aSVedant Kumar   DEFINE_NESTABLE_TRAVERSAL(CXXTryStmt)
2686186971aSVedant Kumar   DEFINE_NESTABLE_TRAVERSAL(CXXCatchStmt)
2696186971aSVedant Kumar 
2706186971aSVedant Kumar   /// Get version \p HashVersion of the PGO hash for \p S.
2716186971aSVedant Kumar   PGOHash::HashType getHashType(PGOHashVersion HashVersion, const Stmt *S) {
272d8931425SBob Wilson     switch (S->getStmtClass()) {
273d8931425SBob Wilson     default:
274d8931425SBob Wilson       break;
275d8931425SBob Wilson     case Stmt::LabelStmtClass:
2764bc7731aSDuncan P. N. Exon Smith       return PGOHash::LabelStmt;
277d8931425SBob Wilson     case Stmt::WhileStmtClass:
2784bc7731aSDuncan P. N. Exon Smith       return PGOHash::WhileStmt;
279d8931425SBob Wilson     case Stmt::DoStmtClass:
2804bc7731aSDuncan P. N. Exon Smith       return PGOHash::DoStmt;
281d8931425SBob Wilson     case Stmt::ForStmtClass:
2824bc7731aSDuncan P. N. Exon Smith       return PGOHash::ForStmt;
283d8931425SBob Wilson     case Stmt::CXXForRangeStmtClass:
2844bc7731aSDuncan P. N. Exon Smith       return PGOHash::CXXForRangeStmt;
285d8931425SBob Wilson     case Stmt::ObjCForCollectionStmtClass:
2864bc7731aSDuncan P. N. Exon Smith       return PGOHash::ObjCForCollectionStmt;
287d8931425SBob Wilson     case Stmt::SwitchStmtClass:
2884bc7731aSDuncan P. N. Exon Smith       return PGOHash::SwitchStmt;
289d8931425SBob Wilson     case Stmt::CaseStmtClass:
2904bc7731aSDuncan P. N. Exon Smith       return PGOHash::CaseStmt;
291d8931425SBob Wilson     case Stmt::DefaultStmtClass:
2924bc7731aSDuncan P. N. Exon Smith       return PGOHash::DefaultStmt;
293d8931425SBob Wilson     case Stmt::IfStmtClass:
2944bc7731aSDuncan P. N. Exon Smith       return PGOHash::IfStmt;
295d8931425SBob Wilson     case Stmt::CXXTryStmtClass:
2964bc7731aSDuncan P. N. Exon Smith       return PGOHash::CXXTryStmt;
297d8931425SBob Wilson     case Stmt::CXXCatchStmtClass:
2984bc7731aSDuncan P. N. Exon Smith       return PGOHash::CXXCatchStmt;
299d8931425SBob Wilson     case Stmt::ConditionalOperatorClass:
3004bc7731aSDuncan P. N. Exon Smith       return PGOHash::ConditionalOperator;
301d8931425SBob Wilson     case Stmt::BinaryConditionalOperatorClass:
3024bc7731aSDuncan P. N. Exon Smith       return PGOHash::BinaryConditionalOperator;
303d8931425SBob Wilson     case Stmt::BinaryOperatorClass: {
304d8931425SBob Wilson       const BinaryOperator *BO = cast<BinaryOperator>(S);
3054bc7731aSDuncan P. N. Exon Smith       if (BO->getOpcode() == BO_LAnd)
3064bc7731aSDuncan P. N. Exon Smith         return PGOHash::BinaryOperatorLAnd;
3074bc7731aSDuncan P. N. Exon Smith       if (BO->getOpcode() == BO_LOr)
3084bc7731aSDuncan P. N. Exon Smith         return PGOHash::BinaryOperatorLOr;
309de02a75eSserge-sans-paille       if (HashVersion >= PGO_HASH_V2) {
3106186971aSVedant Kumar         switch (BO->getOpcode()) {
3116186971aSVedant Kumar         default:
3126186971aSVedant Kumar           break;
3136186971aSVedant Kumar         case BO_LT:
3146186971aSVedant Kumar           return PGOHash::BinaryOperatorLT;
3156186971aSVedant Kumar         case BO_GT:
3166186971aSVedant Kumar           return PGOHash::BinaryOperatorGT;
3176186971aSVedant Kumar         case BO_LE:
3186186971aSVedant Kumar           return PGOHash::BinaryOperatorLE;
3196186971aSVedant Kumar         case BO_GE:
3206186971aSVedant Kumar           return PGOHash::BinaryOperatorGE;
3216186971aSVedant Kumar         case BO_EQ:
3226186971aSVedant Kumar           return PGOHash::BinaryOperatorEQ;
3236186971aSVedant Kumar         case BO_NE:
3246186971aSVedant Kumar           return PGOHash::BinaryOperatorNE;
3256186971aSVedant Kumar         }
3266186971aSVedant Kumar       }
327d8931425SBob Wilson       break;
328ef512b99SJustin Bogner     }
329ef512b99SJustin Bogner     }
3306186971aSVedant Kumar 
331de02a75eSserge-sans-paille     if (HashVersion >= PGO_HASH_V2) {
3326186971aSVedant Kumar       switch (S->getStmtClass()) {
3336186971aSVedant Kumar       default:
3346186971aSVedant Kumar         break;
3356186971aSVedant Kumar       case Stmt::GotoStmtClass:
3366186971aSVedant Kumar         return PGOHash::GotoStmt;
3376186971aSVedant Kumar       case Stmt::IndirectGotoStmtClass:
3386186971aSVedant Kumar         return PGOHash::IndirectGotoStmt;
3396186971aSVedant Kumar       case Stmt::BreakStmtClass:
3406186971aSVedant Kumar         return PGOHash::BreakStmt;
3416186971aSVedant Kumar       case Stmt::ContinueStmtClass:
3426186971aSVedant Kumar         return PGOHash::ContinueStmt;
3436186971aSVedant Kumar       case Stmt::ReturnStmtClass:
3446186971aSVedant Kumar         return PGOHash::ReturnStmt;
3456186971aSVedant Kumar       case Stmt::CXXThrowExprClass:
3466186971aSVedant Kumar         return PGOHash::ThrowExpr;
3476186971aSVedant Kumar       case Stmt::UnaryOperatorClass: {
3486186971aSVedant Kumar         const UnaryOperator *UO = cast<UnaryOperator>(S);
3496186971aSVedant Kumar         if (UO->getOpcode() == UO_LNot)
3506186971aSVedant Kumar           return PGOHash::UnaryOperatorLNot;
3516186971aSVedant Kumar         break;
3526186971aSVedant Kumar       }
3536186971aSVedant Kumar       }
3546186971aSVedant Kumar     }
3556186971aSVedant Kumar 
3564bc7731aSDuncan P. N. Exon Smith     return PGOHash::None;
357ef512b99SJustin Bogner   }
358ef512b99SJustin Bogner };
359bf854f0fSBob Wilson 
360bf854f0fSBob Wilson /// A StmtVisitor that propagates the raw counts through the AST and
361bf854f0fSBob Wilson /// records the count at statements where the value may change.
362bf854f0fSBob Wilson struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
363bf854f0fSBob Wilson   /// PGO state.
364bf854f0fSBob Wilson   CodeGenPGO &PGO;
365bf854f0fSBob Wilson 
366bf854f0fSBob Wilson   /// A flag that is set when the current count should be recorded on the
367bf854f0fSBob Wilson   /// next statement, such as at the exit of a loop.
368bf854f0fSBob Wilson   bool RecordNextStmtCount;
369bf854f0fSBob Wilson 
370a909abfdSJustin Bogner   /// The count at the current location in the traversal.
371a909abfdSJustin Bogner   uint64_t CurrentCount;
372a909abfdSJustin Bogner 
373bf854f0fSBob Wilson   /// The map of statements to count values.
3743586be72SDuncan P. N. Exon Smith   llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
375bf854f0fSBob Wilson 
376bf854f0fSBob Wilson   /// BreakContinueStack - Keep counts of breaks and continues inside loops.
377bf854f0fSBob Wilson   struct BreakContinue {
378bf854f0fSBob Wilson     uint64_t BreakCount;
379bf854f0fSBob Wilson     uint64_t ContinueCount;
380bf854f0fSBob Wilson     BreakContinue() : BreakCount(0), ContinueCount(0) {}
381bf854f0fSBob Wilson   };
382bf854f0fSBob Wilson   SmallVector<BreakContinue, 8> BreakContinueStack;
383bf854f0fSBob Wilson 
3843586be72SDuncan P. N. Exon Smith   ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
3853586be72SDuncan P. N. Exon Smith                       CodeGenPGO &PGO)
3863586be72SDuncan P. N. Exon Smith       : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
387bf854f0fSBob Wilson 
388bf854f0fSBob Wilson   void RecordStmtCount(const Stmt *S) {
389bf854f0fSBob Wilson     if (RecordNextStmtCount) {
390a909abfdSJustin Bogner       CountMap[S] = CurrentCount;
391bf854f0fSBob Wilson       RecordNextStmtCount = false;
392bf854f0fSBob Wilson     }
393bf854f0fSBob Wilson   }
394bf854f0fSBob Wilson 
39507193cc8SJustin Bogner   /// Set and return the current count.
39607193cc8SJustin Bogner   uint64_t setCount(uint64_t Count) {
397a909abfdSJustin Bogner     CurrentCount = Count;
39807193cc8SJustin Bogner     return Count;
39907193cc8SJustin Bogner   }
40007193cc8SJustin Bogner 
401bf854f0fSBob Wilson   void VisitStmt(const Stmt *S) {
402bf854f0fSBob Wilson     RecordStmtCount(S);
403642f173aSBenjamin Kramer     for (const Stmt *Child : S->children())
404642f173aSBenjamin Kramer       if (Child)
405642f173aSBenjamin Kramer         this->Visit(Child);
406bf854f0fSBob Wilson   }
407bf854f0fSBob Wilson 
4084a2f5ae8SDuncan P. N. Exon Smith   void VisitFunctionDecl(const FunctionDecl *D) {
409d8931425SBob Wilson     // Counter tracks entry to the function body.
41007193cc8SJustin Bogner     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
41107193cc8SJustin Bogner     CountMap[D->getBody()] = BodyCount;
4124a2f5ae8SDuncan P. N. Exon Smith     Visit(D->getBody());
413bf854f0fSBob Wilson   }
414bf854f0fSBob Wilson 
415191ec63bSJustin Bogner   // Skip lambda expressions. We visit these as FunctionDecls when we're
416191ec63bSJustin Bogner   // generating them and aren't interested in the body when generating a
417191ec63bSJustin Bogner   // parent context.
418191ec63bSJustin Bogner   void VisitLambdaExpr(const LambdaExpr *LE) {}
419191ec63bSJustin Bogner 
42081ab90f7SJustin Bogner   void VisitCapturedDecl(const CapturedDecl *D) {
42181ab90f7SJustin Bogner     // Counter tracks entry to the capture body.
42207193cc8SJustin Bogner     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
42307193cc8SJustin Bogner     CountMap[D->getBody()] = BodyCount;
42481ab90f7SJustin Bogner     Visit(D->getBody());
42581ab90f7SJustin Bogner   }
42681ab90f7SJustin Bogner 
4274a2f5ae8SDuncan P. N. Exon Smith   void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
428d8931425SBob Wilson     // Counter tracks entry to the method body.
42907193cc8SJustin Bogner     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
43007193cc8SJustin Bogner     CountMap[D->getBody()] = BodyCount;
4314a2f5ae8SDuncan P. N. Exon Smith     Visit(D->getBody());
4325ec8fe19SBob Wilson   }
4335ec8fe19SBob Wilson 
4344a2f5ae8SDuncan P. N. Exon Smith   void VisitBlockDecl(const BlockDecl *D) {
435d8931425SBob Wilson     // Counter tracks entry to the block body.
43607193cc8SJustin Bogner     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
43707193cc8SJustin Bogner     CountMap[D->getBody()] = BodyCount;
4384a2f5ae8SDuncan P. N. Exon Smith     Visit(D->getBody());
439c845c00aSBob Wilson   }
440c845c00aSBob Wilson 
441bf854f0fSBob Wilson   void VisitReturnStmt(const ReturnStmt *S) {
442bf854f0fSBob Wilson     RecordStmtCount(S);
443bf854f0fSBob Wilson     if (S->getRetValue())
444bf854f0fSBob Wilson       Visit(S->getRetValue());
445a909abfdSJustin Bogner     CurrentCount = 0;
446bf854f0fSBob Wilson     RecordNextStmtCount = true;
447bf854f0fSBob Wilson   }
448bf854f0fSBob Wilson 
449f959febfSJustin Bogner   void VisitCXXThrowExpr(const CXXThrowExpr *E) {
450f959febfSJustin Bogner     RecordStmtCount(E);
451f959febfSJustin Bogner     if (E->getSubExpr())
452f959febfSJustin Bogner       Visit(E->getSubExpr());
453a909abfdSJustin Bogner     CurrentCount = 0;
454f959febfSJustin Bogner     RecordNextStmtCount = true;
455f959febfSJustin Bogner   }
456f959febfSJustin Bogner 
457bf854f0fSBob Wilson   void VisitGotoStmt(const GotoStmt *S) {
458bf854f0fSBob Wilson     RecordStmtCount(S);
459a909abfdSJustin Bogner     CurrentCount = 0;
460bf854f0fSBob Wilson     RecordNextStmtCount = true;
461bf854f0fSBob Wilson   }
462bf854f0fSBob Wilson 
463bf854f0fSBob Wilson   void VisitLabelStmt(const LabelStmt *S) {
464bf854f0fSBob Wilson     RecordNextStmtCount = false;
465d8931425SBob Wilson     // Counter tracks the block following the label.
46607193cc8SJustin Bogner     uint64_t BlockCount = setCount(PGO.getRegionCount(S));
46707193cc8SJustin Bogner     CountMap[S] = BlockCount;
468bf854f0fSBob Wilson     Visit(S->getSubStmt());
469bf854f0fSBob Wilson   }
470bf854f0fSBob Wilson 
471bf854f0fSBob Wilson   void VisitBreakStmt(const BreakStmt *S) {
472bf854f0fSBob Wilson     RecordStmtCount(S);
473bf854f0fSBob Wilson     assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
474a909abfdSJustin Bogner     BreakContinueStack.back().BreakCount += CurrentCount;
475a909abfdSJustin Bogner     CurrentCount = 0;
476bf854f0fSBob Wilson     RecordNextStmtCount = true;
477bf854f0fSBob Wilson   }
478bf854f0fSBob Wilson 
479bf854f0fSBob Wilson   void VisitContinueStmt(const ContinueStmt *S) {
480bf854f0fSBob Wilson     RecordStmtCount(S);
481bf854f0fSBob Wilson     assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
482a909abfdSJustin Bogner     BreakContinueStack.back().ContinueCount += CurrentCount;
483a909abfdSJustin Bogner     CurrentCount = 0;
484bf854f0fSBob Wilson     RecordNextStmtCount = true;
485bf854f0fSBob Wilson   }
486bf854f0fSBob Wilson 
487bf854f0fSBob Wilson   void VisitWhileStmt(const WhileStmt *S) {
488bf854f0fSBob Wilson     RecordStmtCount(S);
489a909abfdSJustin Bogner     uint64_t ParentCount = CurrentCount;
49007193cc8SJustin Bogner 
491bf854f0fSBob Wilson     BreakContinueStack.push_back(BreakContinue());
492bf854f0fSBob Wilson     // Visit the body region first so the break/continue adjustments can be
493bf854f0fSBob Wilson     // included when visiting the condition.
49407193cc8SJustin Bogner     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
495a909abfdSJustin Bogner     CountMap[S->getBody()] = CurrentCount;
496bf854f0fSBob Wilson     Visit(S->getBody());
497a909abfdSJustin Bogner     uint64_t BackedgeCount = CurrentCount;
498bf854f0fSBob Wilson 
499bf854f0fSBob Wilson     // ...then go back and propagate counts through the condition. The count
500bf854f0fSBob Wilson     // at the start of the condition is the sum of the incoming edges,
501bf854f0fSBob Wilson     // the backedge from the end of the loop body, and the edges from
502bf854f0fSBob Wilson     // continue statements.
503bf854f0fSBob Wilson     BreakContinue BC = BreakContinueStack.pop_back_val();
50407193cc8SJustin Bogner     uint64_t CondCount =
50507193cc8SJustin Bogner         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
50607193cc8SJustin Bogner     CountMap[S->getCond()] = CondCount;
507bf854f0fSBob Wilson     Visit(S->getCond());
50807193cc8SJustin Bogner     setCount(BC.BreakCount + CondCount - BodyCount);
509bf854f0fSBob Wilson     RecordNextStmtCount = true;
510bf854f0fSBob Wilson   }
511bf854f0fSBob Wilson 
512bf854f0fSBob Wilson   void VisitDoStmt(const DoStmt *S) {
513bf854f0fSBob Wilson     RecordStmtCount(S);
51407193cc8SJustin Bogner     uint64_t LoopCount = PGO.getRegionCount(S);
51507193cc8SJustin Bogner 
516bf854f0fSBob Wilson     BreakContinueStack.push_back(BreakContinue());
51707193cc8SJustin Bogner     // The count doesn't include the fallthrough from the parent scope. Add it.
518a909abfdSJustin Bogner     uint64_t BodyCount = setCount(LoopCount + CurrentCount);
51907193cc8SJustin Bogner     CountMap[S->getBody()] = BodyCount;
520bf854f0fSBob Wilson     Visit(S->getBody());
521a909abfdSJustin Bogner     uint64_t BackedgeCount = CurrentCount;
522bf854f0fSBob Wilson 
523bf854f0fSBob Wilson     BreakContinue BC = BreakContinueStack.pop_back_val();
524bf854f0fSBob Wilson     // The count at the start of the condition is equal to the count at the
52507193cc8SJustin Bogner     // end of the body, plus any continues.
52607193cc8SJustin Bogner     uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount);
52707193cc8SJustin Bogner     CountMap[S->getCond()] = CondCount;
528bf854f0fSBob Wilson     Visit(S->getCond());
52907193cc8SJustin Bogner     setCount(BC.BreakCount + CondCount - LoopCount);
530bf854f0fSBob Wilson     RecordNextStmtCount = true;
531bf854f0fSBob Wilson   }
532bf854f0fSBob Wilson 
533bf854f0fSBob Wilson   void VisitForStmt(const ForStmt *S) {
534bf854f0fSBob Wilson     RecordStmtCount(S);
535bf854f0fSBob Wilson     if (S->getInit())
536bf854f0fSBob Wilson       Visit(S->getInit());
53707193cc8SJustin Bogner 
538a909abfdSJustin Bogner     uint64_t ParentCount = CurrentCount;
53907193cc8SJustin Bogner 
540bf854f0fSBob Wilson     BreakContinueStack.push_back(BreakContinue());
541bf854f0fSBob Wilson     // Visit the body region first. (This is basically the same as a while
542bf854f0fSBob Wilson     // loop; see further comments in VisitWhileStmt.)
54307193cc8SJustin Bogner     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
54407193cc8SJustin Bogner     CountMap[S->getBody()] = BodyCount;
545bf854f0fSBob Wilson     Visit(S->getBody());
546a909abfdSJustin Bogner     uint64_t BackedgeCount = CurrentCount;
54707193cc8SJustin Bogner     BreakContinue BC = BreakContinueStack.pop_back_val();
548bf854f0fSBob Wilson 
549bf854f0fSBob Wilson     // The increment is essentially part of the body but it needs to include
550bf854f0fSBob Wilson     // the count for all the continue statements.
551bf854f0fSBob Wilson     if (S->getInc()) {
55207193cc8SJustin Bogner       uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
55307193cc8SJustin Bogner       CountMap[S->getInc()] = IncCount;
554bf854f0fSBob Wilson       Visit(S->getInc());
555bf854f0fSBob Wilson     }
556bf854f0fSBob Wilson 
557bf854f0fSBob Wilson     // ...then go back and propagate counts through the condition.
55807193cc8SJustin Bogner     uint64_t CondCount =
55907193cc8SJustin Bogner         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
560bf854f0fSBob Wilson     if (S->getCond()) {
56107193cc8SJustin Bogner       CountMap[S->getCond()] = CondCount;
562bf854f0fSBob Wilson       Visit(S->getCond());
563bf854f0fSBob Wilson     }
56407193cc8SJustin Bogner     setCount(BC.BreakCount + CondCount - BodyCount);
565bf854f0fSBob Wilson     RecordNextStmtCount = true;
566bf854f0fSBob Wilson   }
567bf854f0fSBob Wilson 
568bf854f0fSBob Wilson   void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
569bf854f0fSBob Wilson     RecordStmtCount(S);
5708baa5001SRichard Smith     if (S->getInit())
5718baa5001SRichard Smith       Visit(S->getInit());
5722e5d4845SJustin Bogner     Visit(S->getLoopVarStmt());
573bf854f0fSBob Wilson     Visit(S->getRangeStmt());
57401694c34SRichard Smith     Visit(S->getBeginStmt());
57501694c34SRichard Smith     Visit(S->getEndStmt());
57607193cc8SJustin Bogner 
577a909abfdSJustin Bogner     uint64_t ParentCount = CurrentCount;
578bf854f0fSBob Wilson     BreakContinueStack.push_back(BreakContinue());
579bf854f0fSBob Wilson     // Visit the body region first. (This is basically the same as a while
580bf854f0fSBob Wilson     // loop; see further comments in VisitWhileStmt.)
58107193cc8SJustin Bogner     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
58207193cc8SJustin Bogner     CountMap[S->getBody()] = BodyCount;
583bf854f0fSBob Wilson     Visit(S->getBody());
584a909abfdSJustin Bogner     uint64_t BackedgeCount = CurrentCount;
58507193cc8SJustin Bogner     BreakContinue BC = BreakContinueStack.pop_back_val();
586bf854f0fSBob Wilson 
587bf854f0fSBob Wilson     // The increment is essentially part of the body but it needs to include
588bf854f0fSBob Wilson     // the count for all the continue statements.
58907193cc8SJustin Bogner     uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
59007193cc8SJustin Bogner     CountMap[S->getInc()] = IncCount;
591bf854f0fSBob Wilson     Visit(S->getInc());
592bf854f0fSBob Wilson 
593bf854f0fSBob Wilson     // ...then go back and propagate counts through the condition.
59407193cc8SJustin Bogner     uint64_t CondCount =
59507193cc8SJustin Bogner         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
59607193cc8SJustin Bogner     CountMap[S->getCond()] = CondCount;
597bf854f0fSBob Wilson     Visit(S->getCond());
59807193cc8SJustin Bogner     setCount(BC.BreakCount + CondCount - BodyCount);
599bf854f0fSBob Wilson     RecordNextStmtCount = true;
600bf854f0fSBob Wilson   }
601bf854f0fSBob Wilson 
602bf854f0fSBob Wilson   void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
603bf854f0fSBob Wilson     RecordStmtCount(S);
604bf854f0fSBob Wilson     Visit(S->getElement());
605a909abfdSJustin Bogner     uint64_t ParentCount = CurrentCount;
606bf854f0fSBob Wilson     BreakContinueStack.push_back(BreakContinue());
60707193cc8SJustin Bogner     // Counter tracks the body of the loop.
60807193cc8SJustin Bogner     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
60907193cc8SJustin Bogner     CountMap[S->getBody()] = BodyCount;
610bf854f0fSBob Wilson     Visit(S->getBody());
611a909abfdSJustin Bogner     uint64_t BackedgeCount = CurrentCount;
612bf854f0fSBob Wilson     BreakContinue BC = BreakContinueStack.pop_back_val();
61307193cc8SJustin Bogner 
61407193cc8SJustin Bogner     setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount -
61507193cc8SJustin Bogner              BodyCount);
616bf854f0fSBob Wilson     RecordNextStmtCount = true;
617bf854f0fSBob Wilson   }
618bf854f0fSBob Wilson 
619bf854f0fSBob Wilson   void VisitSwitchStmt(const SwitchStmt *S) {
620bf854f0fSBob Wilson     RecordStmtCount(S);
621f2a6ec55SVedant Kumar     if (S->getInit())
622f2a6ec55SVedant Kumar       Visit(S->getInit());
623bf854f0fSBob Wilson     Visit(S->getCond());
624a909abfdSJustin Bogner     CurrentCount = 0;
625bf854f0fSBob Wilson     BreakContinueStack.push_back(BreakContinue());
626bf854f0fSBob Wilson     Visit(S->getBody());
627bf854f0fSBob Wilson     // If the switch is inside a loop, add the continue counts.
628bf854f0fSBob Wilson     BreakContinue BC = BreakContinueStack.pop_back_val();
629bf854f0fSBob Wilson     if (!BreakContinueStack.empty())
630bf854f0fSBob Wilson       BreakContinueStack.back().ContinueCount += BC.ContinueCount;
631d8931425SBob Wilson     // Counter tracks the exit block of the switch.
63207193cc8SJustin Bogner     setCount(PGO.getRegionCount(S));
633bf854f0fSBob Wilson     RecordNextStmtCount = true;
634bf854f0fSBob Wilson   }
635bf854f0fSBob Wilson 
63607193cc8SJustin Bogner   void VisitSwitchCase(const SwitchCase *S) {
637bf854f0fSBob Wilson     RecordNextStmtCount = false;
638d8931425SBob Wilson     // Counter for this particular case. This counts only jumps from the
639d8931425SBob Wilson     // switch header and does not include fallthrough from the case before
640d8931425SBob Wilson     // this one.
64107193cc8SJustin Bogner     uint64_t CaseCount = PGO.getRegionCount(S);
642a909abfdSJustin Bogner     setCount(CurrentCount + CaseCount);
64307193cc8SJustin Bogner     // We need the count without fallthrough in the mapping, so it's more useful
64407193cc8SJustin Bogner     // for branch probabilities.
64507193cc8SJustin Bogner     CountMap[S] = CaseCount;
646bf854f0fSBob Wilson     RecordNextStmtCount = true;
647bf854f0fSBob Wilson     Visit(S->getSubStmt());
648bf854f0fSBob Wilson   }
649bf854f0fSBob Wilson 
650bf854f0fSBob Wilson   void VisitIfStmt(const IfStmt *S) {
651bf854f0fSBob Wilson     RecordStmtCount(S);
652a909abfdSJustin Bogner     uint64_t ParentCount = CurrentCount;
6539d2a16b9SVedant Kumar     if (S->getInit())
6549d2a16b9SVedant Kumar       Visit(S->getInit());
655bf854f0fSBob Wilson     Visit(S->getCond());
656bf854f0fSBob Wilson 
65707193cc8SJustin Bogner     // Counter tracks the "then" part of an if statement. The count for
65807193cc8SJustin Bogner     // the "else" part, if it exists, will be calculated from this counter.
65907193cc8SJustin Bogner     uint64_t ThenCount = setCount(PGO.getRegionCount(S));
66007193cc8SJustin Bogner     CountMap[S->getThen()] = ThenCount;
661bf854f0fSBob Wilson     Visit(S->getThen());
662a909abfdSJustin Bogner     uint64_t OutCount = CurrentCount;
663bf854f0fSBob Wilson 
66407193cc8SJustin Bogner     uint64_t ElseCount = ParentCount - ThenCount;
665bf854f0fSBob Wilson     if (S->getElse()) {
66607193cc8SJustin Bogner       setCount(ElseCount);
66707193cc8SJustin Bogner       CountMap[S->getElse()] = ElseCount;
668bf854f0fSBob Wilson       Visit(S->getElse());
669a909abfdSJustin Bogner       OutCount += CurrentCount;
67007193cc8SJustin Bogner     } else
67107193cc8SJustin Bogner       OutCount += ElseCount;
67207193cc8SJustin Bogner     setCount(OutCount);
673bf854f0fSBob Wilson     RecordNextStmtCount = true;
674bf854f0fSBob Wilson   }
675bf854f0fSBob Wilson 
676bf854f0fSBob Wilson   void VisitCXXTryStmt(const CXXTryStmt *S) {
677bf854f0fSBob Wilson     RecordStmtCount(S);
678bf854f0fSBob Wilson     Visit(S->getTryBlock());
679bf854f0fSBob Wilson     for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
680bf854f0fSBob Wilson       Visit(S->getHandler(I));
681d8931425SBob Wilson     // Counter tracks the continuation block of the try statement.
68207193cc8SJustin Bogner     setCount(PGO.getRegionCount(S));
683bf854f0fSBob Wilson     RecordNextStmtCount = true;
684bf854f0fSBob Wilson   }
685bf854f0fSBob Wilson 
686bf854f0fSBob Wilson   void VisitCXXCatchStmt(const CXXCatchStmt *S) {
687bf854f0fSBob Wilson     RecordNextStmtCount = false;
688d8931425SBob Wilson     // Counter tracks the catch statement's handler block.
68907193cc8SJustin Bogner     uint64_t CatchCount = setCount(PGO.getRegionCount(S));
69007193cc8SJustin Bogner     CountMap[S] = CatchCount;
691bf854f0fSBob Wilson     Visit(S->getHandlerBlock());
692bf854f0fSBob Wilson   }
693bf854f0fSBob Wilson 
694e4ca441aSJustin Bogner   void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
695bf854f0fSBob Wilson     RecordStmtCount(E);
696a909abfdSJustin Bogner     uint64_t ParentCount = CurrentCount;
697bf854f0fSBob Wilson     Visit(E->getCond());
698bf854f0fSBob Wilson 
69907193cc8SJustin Bogner     // Counter tracks the "true" part of a conditional operator. The
70007193cc8SJustin Bogner     // count in the "false" part will be calculated from this counter.
70107193cc8SJustin Bogner     uint64_t TrueCount = setCount(PGO.getRegionCount(E));
70207193cc8SJustin Bogner     CountMap[E->getTrueExpr()] = TrueCount;
703bf854f0fSBob Wilson     Visit(E->getTrueExpr());
704a909abfdSJustin Bogner     uint64_t OutCount = CurrentCount;
705bf854f0fSBob Wilson 
70607193cc8SJustin Bogner     uint64_t FalseCount = setCount(ParentCount - TrueCount);
70707193cc8SJustin Bogner     CountMap[E->getFalseExpr()] = FalseCount;
708bf854f0fSBob Wilson     Visit(E->getFalseExpr());
709a909abfdSJustin Bogner     OutCount += CurrentCount;
710bf854f0fSBob Wilson 
71107193cc8SJustin Bogner     setCount(OutCount);
712bf854f0fSBob Wilson     RecordNextStmtCount = true;
713bf854f0fSBob Wilson   }
714bf854f0fSBob Wilson 
715bf854f0fSBob Wilson   void VisitBinLAnd(const BinaryOperator *E) {
716bf854f0fSBob Wilson     RecordStmtCount(E);
717a909abfdSJustin Bogner     uint64_t ParentCount = CurrentCount;
718bf854f0fSBob Wilson     Visit(E->getLHS());
71907193cc8SJustin Bogner     // Counter tracks the right hand side of a logical and operator.
72007193cc8SJustin Bogner     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
72107193cc8SJustin Bogner     CountMap[E->getRHS()] = RHSCount;
722bf854f0fSBob Wilson     Visit(E->getRHS());
723a909abfdSJustin Bogner     setCount(ParentCount + RHSCount - CurrentCount);
724bf854f0fSBob Wilson     RecordNextStmtCount = true;
725bf854f0fSBob Wilson   }
726bf854f0fSBob Wilson 
727bf854f0fSBob Wilson   void VisitBinLOr(const BinaryOperator *E) {
728bf854f0fSBob Wilson     RecordStmtCount(E);
729a909abfdSJustin Bogner     uint64_t ParentCount = CurrentCount;
730bf854f0fSBob Wilson     Visit(E->getLHS());
73107193cc8SJustin Bogner     // Counter tracks the right hand side of a logical or operator.
73207193cc8SJustin Bogner     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
73307193cc8SJustin Bogner     CountMap[E->getRHS()] = RHSCount;
734bf854f0fSBob Wilson     Visit(E->getRHS());
735a909abfdSJustin Bogner     setCount(ParentCount + RHSCount - CurrentCount);
736bf854f0fSBob Wilson     RecordNextStmtCount = true;
737bf854f0fSBob Wilson   }
738bf854f0fSBob Wilson };
739dcfba334SHans Wennborg } // end anonymous namespace
740ef512b99SJustin Bogner 
7414bc7731aSDuncan P. N. Exon Smith void PGOHash::combine(HashType Type) {
7424bc7731aSDuncan P. N. Exon Smith   // Check that we never combine 0 and only have six bits.
7434bc7731aSDuncan P. N. Exon Smith   assert(Type && "Hash is invalid: unexpected type 0");
7444bc7731aSDuncan P. N. Exon Smith   assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
7454bc7731aSDuncan P. N. Exon Smith 
7464bc7731aSDuncan P. N. Exon Smith   // Pass through MD5 if enough work has built up.
7474bc7731aSDuncan P. N. Exon Smith   if (Count && Count % NumTypesPerWord == 0) {
7484bc7731aSDuncan P. N. Exon Smith     using namespace llvm::support;
7494bc7731aSDuncan P. N. Exon Smith     uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
7504bc7731aSDuncan P. N. Exon Smith     MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
7514bc7731aSDuncan P. N. Exon Smith     Working = 0;
7524bc7731aSDuncan P. N. Exon Smith   }
7534bc7731aSDuncan P. N. Exon Smith 
7544bc7731aSDuncan P. N. Exon Smith   // Accumulate the current type.
7554bc7731aSDuncan P. N. Exon Smith   ++Count;
7564bc7731aSDuncan P. N. Exon Smith   Working = Working << NumBitsPerType | Type;
7574bc7731aSDuncan P. N. Exon Smith }
7584bc7731aSDuncan P. N. Exon Smith 
7594bc7731aSDuncan P. N. Exon Smith uint64_t PGOHash::finalize() {
7604bc7731aSDuncan P. N. Exon Smith   // Use Working as the hash directly if we never used MD5.
7614bc7731aSDuncan P. N. Exon Smith   if (Count <= NumTypesPerWord)
7624bc7731aSDuncan P. N. Exon Smith     // No need to byte swap here, since none of the math was endian-dependent.
7634bc7731aSDuncan P. N. Exon Smith     // This number will be byte-swapped as required on endianness transitions,
7644bc7731aSDuncan P. N. Exon Smith     // so we will see the same value on the other side.
7654bc7731aSDuncan P. N. Exon Smith     return Working;
7664bc7731aSDuncan P. N. Exon Smith 
7674bc7731aSDuncan P. N. Exon Smith   // Check for remaining work in Working.
768de02a75eSserge-sans-paille   if (Working) {
769de02a75eSserge-sans-paille     // Keep the buggy behavior from v1 and v2 for backward-compatibility. This
770de02a75eSserge-sans-paille     // is buggy because it converts a uint64_t into an array of uint8_t.
771de02a75eSserge-sans-paille     if (HashVersion < PGO_HASH_V3) {
772de02a75eSserge-sans-paille       MD5.update({(uint8_t)Working});
773de02a75eSserge-sans-paille     } else {
774de02a75eSserge-sans-paille       using namespace llvm::support;
775de02a75eSserge-sans-paille       uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
776de02a75eSserge-sans-paille       MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
777de02a75eSserge-sans-paille     }
778de02a75eSserge-sans-paille   }
7794bc7731aSDuncan P. N. Exon Smith 
7804bc7731aSDuncan P. N. Exon Smith   // Finalize the MD5 and return the hash.
7814bc7731aSDuncan P. N. Exon Smith   llvm::MD5::MD5Result Result;
7824bc7731aSDuncan P. N. Exon Smith   MD5.final(Result);
78382a0c97bSZachary Turner   return Result.low();
7844bc7731aSDuncan P. N. Exon Smith }
7854bc7731aSDuncan P. N. Exon Smith 
7863a561459SSerge Pavlov void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
7873a561459SSerge Pavlov   const Decl *D = GD.getDecl();
78833d0a1ccSVedant Kumar   if (!D->hasBody())
78933d0a1ccSVedant Kumar     return;
79033d0a1ccSVedant Kumar 
791c7b683c1SMichael Liao   // Skip CUDA/HIP kernel launch stub functions.
792c7b683c1SMichael Liao   if (CGM.getLangOpts().CUDA && !CGM.getLangOpts().CUDAIsDevice &&
793c7b683c1SMichael Liao       D->hasAttr<CUDAGlobalAttr>())
794c7b683c1SMichael Liao     return;
795c7b683c1SMichael Liao 
7969837ef56SRong Xu   bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
797837a6f6fSJustin Bogner   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
798837a6f6fSJustin Bogner   if (!InstrumentRegions && !PGOReader)
799ef512b99SJustin Bogner     return;
8003212b18bSJustin Bogner   if (D->isImplicit())
801ef512b99SJustin Bogner     return;
8023a561459SSerge Pavlov   // Constructors and destructors may be represented by several functions in IR.
8033a561459SSerge Pavlov   // If so, instrument only base variant, others are implemented by delegation
8043a561459SSerge Pavlov   // to the base one, it would be counted twice otherwise.
8057f809b2fSVedant Kumar   if (CGM.getTarget().getCXXABI().hasConstructorVariants()) {
8067f809b2fSVedant Kumar     if (const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
8077f809b2fSVedant Kumar       if (GD.getCtorType() != Ctor_Base &&
8087f809b2fSVedant Kumar           CodeGenFunction::IsConstructorDelegationValid(CCD))
8093a561459SSerge Pavlov         return;
8103a561459SSerge Pavlov   }
811f9ef9f86SReid Kleckner   if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
812f9ef9f86SReid Kleckner     return;
813f9ef9f86SReid Kleckner 
814*bb9eb198SPetr Hosek   if (Fn->hasFnAttribute(llvm::Attribute::NoProfile))
815*bb9eb198SPetr Hosek     return;
816*bb9eb198SPetr Hosek 
817ee02499aSAlex Lorenz   CGM.ClearUnusedCoverageMapping(D);
818da1ebedeSBob Wilson   setFuncName(Fn);
8197c41451bSDuncan P. N. Exon Smith 
820ef512b99SJustin Bogner   mapRegionCounters(D);
821ee02499aSAlex Lorenz   if (CGM.getCodeGenOpts().CoverageMapping)
822ee02499aSAlex Lorenz     emitCounterRegionMapping(D);
823837a6f6fSJustin Bogner   if (PGOReader) {
82440b8ba14SJustin Bogner     SourceManager &SM = CGM.getContext().getSourceManager();
82540b8ba14SJustin Bogner     loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
826bf854f0fSBob Wilson     computeRegionCounts(D);
827837a6f6fSJustin Bogner     applyFunctionAttributes(PGOReader, Fn);
828bf854f0fSBob Wilson   }
829ef512b99SJustin Bogner }
830ef512b99SJustin Bogner 
831ef512b99SJustin Bogner void CodeGenPGO::mapRegionCounters(const Decl *D) {
8326186971aSVedant Kumar   // Use the latest hash version when inserting instrumentation, but use the
8336186971aSVedant Kumar   // version in the indexed profile if we're reading PGO data.
8346186971aSVedant Kumar   PGOHashVersion HashVersion = PGO_HASH_LATEST;
8359f2967bcSAlan Phipps   uint64_t ProfileVersion = llvm::IndexedInstrProf::Version;
8369f2967bcSAlan Phipps   if (auto *PGOReader = CGM.getPGOReader()) {
8376186971aSVedant Kumar     HashVersion = getPGOHashVersion(PGOReader, CGM);
8389f2967bcSAlan Phipps     ProfileVersion = PGOReader->getVersion();
8399f2967bcSAlan Phipps   }
8406186971aSVedant Kumar 
8411b67cfd4SDuncan P. N. Exon Smith   RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
8429f2967bcSAlan Phipps   MapRegionCounters Walker(HashVersion, ProfileVersion, *RegionCounterMap);
843ef512b99SJustin Bogner   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
844d8931425SBob Wilson     Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
8455ec8fe19SBob Wilson   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
846d8931425SBob Wilson     Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
847c845c00aSBob Wilson   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
848d8931425SBob Wilson     Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
84981ab90f7SJustin Bogner   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
85081ab90f7SJustin Bogner     Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
8513212b18bSJustin Bogner   assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
852ef512b99SJustin Bogner   NumRegionCounters = Walker.NextCounter;
8534bc7731aSDuncan P. N. Exon Smith   FunctionHash = Walker.Hash.finalize();
854ef512b99SJustin Bogner }
855ef512b99SJustin Bogner 
856c468bb8bSVedant Kumar bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) {
857bc370f0cSVedant Kumar   if (!D->getBody())
858bc370f0cSVedant Kumar     return true;
859bc370f0cSVedant Kumar 
860c7b683c1SMichael Liao   // Skip host-only functions in the CUDA device compilation and device-only
861c7b683c1SMichael Liao   // functions in the host compilation. Just roughly filter them out based on
862c7b683c1SMichael Liao   // the function attributes. If there are effectively host-only or device-only
863c7b683c1SMichael Liao   // ones, their coverage mapping may still be generated.
864c7b683c1SMichael Liao   if (CGM.getLangOpts().CUDA &&
865c7b683c1SMichael Liao       ((CGM.getLangOpts().CUDAIsDevice && !D->hasAttr<CUDADeviceAttr>() &&
866c7b683c1SMichael Liao         !D->hasAttr<CUDAGlobalAttr>()) ||
867c7b683c1SMichael Liao        (!CGM.getLangOpts().CUDAIsDevice &&
868c7b683c1SMichael Liao         (D->hasAttr<CUDAGlobalAttr>() ||
869c7b683c1SMichael Liao          (!D->hasAttr<CUDAHostAttr>() && D->hasAttr<CUDADeviceAttr>())))))
870c7b683c1SMichael Liao     return true;
871c7b683c1SMichael Liao 
872c468bb8bSVedant Kumar   // Don't map the functions in system headers.
873c468bb8bSVedant Kumar   const auto &SM = CGM.getContext().getSourceManager();
874f2ceec48SStephen Kelly   auto Loc = D->getBody()->getBeginLoc();
875c468bb8bSVedant Kumar   return SM.isInSystemHeader(Loc);
876c468bb8bSVedant Kumar }
877c468bb8bSVedant Kumar 
878c468bb8bSVedant Kumar void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
879c468bb8bSVedant Kumar   if (skipRegionMappingForDecl(D))
880ee02499aSAlex Lorenz     return;
881ee02499aSAlex Lorenz 
882970ac605SJustin Bogner   std::string CoverageMapping;
883ee02499aSAlex Lorenz   llvm::raw_string_ostream OS(CoverageMapping);
884ee02499aSAlex Lorenz   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
885ee02499aSAlex Lorenz                                 CGM.getContext().getSourceManager(),
886e5ee6c58SJustin Bogner                                 CGM.getLangOpts(), RegionCounterMap.get());
887ee02499aSAlex Lorenz   MappingGen.emitCounterMapping(D, OS);
888ee02499aSAlex Lorenz   OS.flush();
889970ac605SJustin Bogner 
890970ac605SJustin Bogner   if (CoverageMapping.empty())
891970ac605SJustin Bogner     return;
892970ac605SJustin Bogner 
893970ac605SJustin Bogner   CGM.getCoverageMapping()->addFunctionMappingRecord(
894970ac605SJustin Bogner       FuncNameVar, FuncName, FunctionHash, CoverageMapping);
895ee02499aSAlex Lorenz }
896ee02499aSAlex Lorenz 
897ee02499aSAlex Lorenz void
89860d852baSJustin Bogner CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef Name,
899ee02499aSAlex Lorenz                                     llvm::GlobalValue::LinkageTypes Linkage) {
900c468bb8bSVedant Kumar   if (skipRegionMappingForDecl(D))
901ee02499aSAlex Lorenz     return;
902ee02499aSAlex Lorenz 
903970ac605SJustin Bogner   std::string CoverageMapping;
904ee02499aSAlex Lorenz   llvm::raw_string_ostream OS(CoverageMapping);
905ee02499aSAlex Lorenz   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
906ee02499aSAlex Lorenz                                 CGM.getContext().getSourceManager(),
907ee02499aSAlex Lorenz                                 CGM.getLangOpts());
908ee02499aSAlex Lorenz   MappingGen.emitEmptyMapping(D, OS);
909ee02499aSAlex Lorenz   OS.flush();
910970ac605SJustin Bogner 
911970ac605SJustin Bogner   if (CoverageMapping.empty())
912970ac605SJustin Bogner     return;
913970ac605SJustin Bogner 
91460d852baSJustin Bogner   setFuncName(Name, Linkage);
915970ac605SJustin Bogner   CGM.getCoverageMapping()->addFunctionMappingRecord(
9162129ae53SXinliang David Li       FuncNameVar, FuncName, FunctionHash, CoverageMapping, false);
917ee02499aSAlex Lorenz }
918ee02499aSAlex Lorenz 
919bf854f0fSBob Wilson void CodeGenPGO::computeRegionCounts(const Decl *D) {
9201b67cfd4SDuncan P. N. Exon Smith   StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
9213586be72SDuncan P. N. Exon Smith   ComputeRegionCounts Walker(*StmtCountMap, *this);
922bf854f0fSBob Wilson   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
923bf854f0fSBob Wilson     Walker.VisitFunctionDecl(FD);
9245ec8fe19SBob Wilson   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
9255ec8fe19SBob Wilson     Walker.VisitObjCMethodDecl(MD);
926c845c00aSBob Wilson   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
927c845c00aSBob Wilson     Walker.VisitBlockDecl(BD);
92881ab90f7SJustin Bogner   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
92981ab90f7SJustin Bogner     Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
930bf854f0fSBob Wilson }
931bf854f0fSBob Wilson 
932837a6f6fSJustin Bogner void
933837a6f6fSJustin Bogner CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
9344c9c45c0SJustin Bogner                                     llvm::Function *Fn) {
9354c9c45c0SJustin Bogner   if (!haveRegionCounts())
9364c9c45c0SJustin Bogner     return;
9374c9c45c0SJustin Bogner 
938dcfba334SHans Wennborg   uint64_t FunctionCount = getRegionCount(nullptr);
939aa8b1cb8SDiego Novillo   Fn->setEntryCount(FunctionCount);
9404c9c45c0SJustin Bogner }
9414c9c45c0SJustin Bogner 
942502bbfafSVedant Kumar void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
943502bbfafSVedant Kumar                                       llvm::Value *StepV) {
9449837ef56SRong Xu   if (!CGM.getCodeGenOpts().hasProfileClangInstr() || !RegionCounterMap)
945ef512b99SJustin Bogner     return;
9469f5260abSDuncan P. N. Exon Smith   if (!Builder.GetInsertBlock())
947203f91e3SJustin Bogner     return;
94866242d6cSJustin Bogner 
94966242d6cSJustin Bogner   unsigned Counter = (*RegionCounterMap)[S];
950970ac605SJustin Bogner   auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
951502bbfafSVedant Kumar 
952502bbfafSVedant Kumar   llvm::Value *Args[] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
953a45f315eSVedant Kumar                          Builder.getInt64(FunctionHash),
954a45f315eSVedant Kumar                          Builder.getInt32(NumRegionCounters),
955502bbfafSVedant Kumar                          Builder.getInt32(Counter), StepV};
956502bbfafSVedant Kumar   if (!StepV)
957502bbfafSVedant Kumar     Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
958502bbfafSVedant Kumar                        makeArrayRef(Args, 4));
959502bbfafSVedant Kumar   else
960502bbfafSVedant Kumar     Builder.CreateCall(
961502bbfafSVedant Kumar         CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment_step),
962502bbfafSVedant Kumar         makeArrayRef(Args));
963ef512b99SJustin Bogner }
964ef512b99SJustin Bogner 
965518276a5SBetul Buyukkurt // This method either inserts a call to the profile run-time during
966518276a5SBetul Buyukkurt // instrumentation or puts profile data into metadata for PGO use.
967518276a5SBetul Buyukkurt void CodeGenPGO::valueProfile(CGBuilderTy &Builder, uint32_t ValueKind,
968518276a5SBetul Buyukkurt     llvm::Instruction *ValueSite, llvm::Value *ValuePtr) {
969518276a5SBetul Buyukkurt 
970518276a5SBetul Buyukkurt   if (!EnableValueProfiling)
971518276a5SBetul Buyukkurt     return;
972518276a5SBetul Buyukkurt 
973518276a5SBetul Buyukkurt   if (!ValuePtr || !ValueSite || !Builder.GetInsertBlock())
974518276a5SBetul Buyukkurt     return;
975518276a5SBetul Buyukkurt 
9763da993c4SBetul Buyukkurt   if (isa<llvm::Constant>(ValuePtr))
9773da993c4SBetul Buyukkurt     return;
9783da993c4SBetul Buyukkurt 
9799837ef56SRong Xu   bool InstrumentValueSites = CGM.getCodeGenOpts().hasProfileClangInstr();
980518276a5SBetul Buyukkurt   if (InstrumentValueSites && RegionCounterMap) {
981cb6f5f16SBetul Buyukkurt     auto BuilderInsertPoint = Builder.saveIP();
982cb6f5f16SBetul Buyukkurt     Builder.SetInsertPoint(ValueSite);
983518276a5SBetul Buyukkurt     llvm::Value *Args[5] = {
984cb6f5f16SBetul Buyukkurt         llvm::ConstantExpr::getBitCast(FuncNameVar, Builder.getInt8PtrTy()),
985518276a5SBetul Buyukkurt         Builder.getInt64(FunctionHash),
986518276a5SBetul Buyukkurt         Builder.CreatePtrToInt(ValuePtr, Builder.getInt64Ty()),
987518276a5SBetul Buyukkurt         Builder.getInt32(ValueKind),
988518276a5SBetul Buyukkurt         Builder.getInt32(NumValueSites[ValueKind]++)
989518276a5SBetul Buyukkurt     };
990518276a5SBetul Buyukkurt     Builder.CreateCall(
991518276a5SBetul Buyukkurt         CGM.getIntrinsic(llvm::Intrinsic::instrprof_value_profile), Args);
992cb6f5f16SBetul Buyukkurt     Builder.restoreIP(BuilderInsertPoint);
993518276a5SBetul Buyukkurt     return;
994518276a5SBetul Buyukkurt   }
995518276a5SBetul Buyukkurt 
996518276a5SBetul Buyukkurt   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
997518276a5SBetul Buyukkurt   if (PGOReader && haveRegionCounts()) {
998518276a5SBetul Buyukkurt     // We record the top most called three functions at each call site.
999518276a5SBetul Buyukkurt     // Profile metadata contains "VP" string identifying this metadata
1000518276a5SBetul Buyukkurt     // as value profiling data, then a uint32_t value for the value profiling
1001518276a5SBetul Buyukkurt     // kind, a uint64_t value for the total number of times the call is
1002518276a5SBetul Buyukkurt     // executed, followed by the function hash and execution count (uint64_t)
1003518276a5SBetul Buyukkurt     // pairs for each function.
1004518276a5SBetul Buyukkurt     if (NumValueSites[ValueKind] >= ProfRecord->getNumValueSites(ValueKind))
1005518276a5SBetul Buyukkurt       return;
10065527a9ddSXinliang David Li 
10075527a9ddSXinliang David Li     llvm::annotateValueSite(CGM.getModule(), *ValueSite, *ProfRecord,
10085527a9ddSXinliang David Li                             (llvm::InstrProfValueKind)ValueKind,
1009518276a5SBetul Buyukkurt                             NumValueSites[ValueKind]);
1010518276a5SBetul Buyukkurt 
1011518276a5SBetul Buyukkurt     NumValueSites[ValueKind]++;
1012518276a5SBetul Buyukkurt   }
1013518276a5SBetul Buyukkurt }
1014518276a5SBetul Buyukkurt 
101540b8ba14SJustin Bogner void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
101640b8ba14SJustin Bogner                                   bool IsInMainFile) {
101740b8ba14SJustin Bogner   CGM.getPGOStats().addVisited(IsInMainFile);
10187f8cf5bfSJustin Bogner   RegionCounts.clear();
1019fa2d5955SVedant Kumar   llvm::Expected<llvm::InstrProfRecord> RecordExpected =
1020518276a5SBetul Buyukkurt       PGOReader->getInstrProfRecord(FuncName, FunctionHash);
1021fa2d5955SVedant Kumar   if (auto E = RecordExpected.takeError()) {
1022fa2d5955SVedant Kumar     auto IPE = llvm::InstrProfError::take(std::move(E));
1023fa2d5955SVedant Kumar     if (IPE == llvm::instrprof_error::unknown_function)
102440b8ba14SJustin Bogner       CGM.getPGOStats().addMissing(IsInMainFile);
1025fa2d5955SVedant Kumar     else if (IPE == llvm::instrprof_error::hash_mismatch)
10269c6818efSJustin Bogner       CGM.getPGOStats().addMismatched(IsInMainFile);
1027fa2d5955SVedant Kumar     else if (IPE == llvm::instrprof_error::malformed)
10289c6818efSJustin Bogner       // TODO: Consider a more specific warning for this case.
102940b8ba14SJustin Bogner       CGM.getPGOStats().addMismatched(IsInMainFile);
1030518276a5SBetul Buyukkurt     return;
1031e2ef2a09SJustin Bogner   }
1032518276a5SBetul Buyukkurt   ProfRecord =
10332b3d49b6SJonas Devlieghere       std::make_unique<llvm::InstrProfRecord>(std::move(RecordExpected.get()));
1034518276a5SBetul Buyukkurt   RegionCounts = ProfRecord->Counts;
1035ef512b99SJustin Bogner }
1036ef512b99SJustin Bogner 
10375c31b8b9SArthur Eubanks /// Calculate what to divide by to scale weights.
10385c31b8b9SArthur Eubanks ///
10395c31b8b9SArthur Eubanks /// Given the maximum weight, calculate a divisor that will scale all the
10405c31b8b9SArthur Eubanks /// weights to strictly less than UINT32_MAX.
10415c31b8b9SArthur Eubanks static uint64_t calculateWeightScale(uint64_t MaxWeight) {
10425c31b8b9SArthur Eubanks   return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
10435c31b8b9SArthur Eubanks }
10445c31b8b9SArthur Eubanks 
10455c31b8b9SArthur Eubanks /// Scale an individual branch weight (and add 1).
10465c31b8b9SArthur Eubanks ///
10475c31b8b9SArthur Eubanks /// Scale a 64-bit weight down to 32-bits using \c Scale.
104838402dc9SDuncan P. N. Exon Smith ///
104938402dc9SDuncan P. N. Exon Smith /// According to Laplace's Rule of Succession, it is better to compute the
105038402dc9SDuncan P. N. Exon Smith /// weight based on the count plus 1, so universally add 1 to the value.
10515c31b8b9SArthur Eubanks ///
10525c31b8b9SArthur Eubanks /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
10535c31b8b9SArthur Eubanks /// greater than \c Weight.
10545c31b8b9SArthur Eubanks static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
10555c31b8b9SArthur Eubanks   assert(Scale && "scale by 0?");
10565c31b8b9SArthur Eubanks   uint64_t Scaled = Weight / Scale + 1;
10575c31b8b9SArthur Eubanks   assert(Scaled <= UINT32_MAX && "overflow 32-bits");
10585c31b8b9SArthur Eubanks   return Scaled;
10595c31b8b9SArthur Eubanks }
106038402dc9SDuncan P. N. Exon Smith 
106165512647SJustin Bogner llvm::MDNode *CodeGenFunction::createProfileWeights(uint64_t TrueCount,
1062389c8d5bSMark de Wever                                                     uint64_t FalseCount) const {
106338402dc9SDuncan P. N. Exon Smith   // Check for empty weights.
1064ef512b99SJustin Bogner   if (!TrueCount && !FalseCount)
1065a5f804a7SDuncan P. N. Exon Smith     return nullptr;
1066ef512b99SJustin Bogner 
10675c31b8b9SArthur Eubanks   // Calculate how to scale down to 32-bits.
10685c31b8b9SArthur Eubanks   uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
10695c31b8b9SArthur Eubanks 
1070ef512b99SJustin Bogner   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
10715c31b8b9SArthur Eubanks   return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
10725c31b8b9SArthur Eubanks                                       scaleBranchWeight(FalseCount, Scale));
1073ef512b99SJustin Bogner }
1074ef512b99SJustin Bogner 
107565512647SJustin Bogner llvm::MDNode *
1076389c8d5bSMark de Wever CodeGenFunction::createProfileWeights(ArrayRef<uint64_t> Weights) const {
107738402dc9SDuncan P. N. Exon Smith   // We need at least two elements to create meaningful weights.
107838402dc9SDuncan P. N. Exon Smith   if (Weights.size() < 2)
1079a5f804a7SDuncan P. N. Exon Smith     return nullptr;
108038402dc9SDuncan P. N. Exon Smith 
1081f3aefca7SJustin Bogner   // Check for empty weights.
1082f3aefca7SJustin Bogner   uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
1083f3aefca7SJustin Bogner   if (MaxWeight == 0)
1084f3aefca7SJustin Bogner     return nullptr;
1085f3aefca7SJustin Bogner 
10865c31b8b9SArthur Eubanks   // Calculate how to scale down to 32-bits.
10875c31b8b9SArthur Eubanks   uint64_t Scale = calculateWeightScale(MaxWeight);
10885c31b8b9SArthur Eubanks 
10895c31b8b9SArthur Eubanks   SmallVector<uint32_t, 16> ScaledWeights;
1090ef512b99SJustin Bogner   ScaledWeights.reserve(Weights.size());
109138402dc9SDuncan P. N. Exon Smith   for (uint64_t W : Weights)
10925c31b8b9SArthur Eubanks     ScaledWeights.push_back(scaleBranchWeight(W, Scale));
109338402dc9SDuncan P. N. Exon Smith 
109438402dc9SDuncan P. N. Exon Smith   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
1095ef512b99SJustin Bogner   return MDHelper.createBranchWeights(ScaledWeights);
1096ef512b99SJustin Bogner }
1097bf854f0fSBob Wilson 
1098389c8d5bSMark de Wever llvm::MDNode *
1099389c8d5bSMark de Wever CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond,
1100389c8d5bSMark de Wever                                              uint64_t LoopCount) const {
110165512647SJustin Bogner   if (!PGO.haveRegionCounts())
1102a5f804a7SDuncan P. N. Exon Smith     return nullptr;
110365512647SJustin Bogner   Optional<uint64_t> CondCount = PGO.getStmtCount(Cond);
110455b9b11fSHans Wennborg   if (!CondCount || *CondCount == 0)
1105a5f804a7SDuncan P. N. Exon Smith     return nullptr;
110665512647SJustin Bogner   return createProfileWeights(LoopCount,
11071c21c28bSJustin Bogner                               std::max(*CondCount, LoopCount) - LoopCount);
1108bf854f0fSBob Wilson }
1109