xref: /freebsd-src/contrib/llvm-project/clang/lib/CodeGen/CodeGenPGO.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Instrumentation-based profile-guided optimization
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "CodeGenPGO.h"
140b57cec5SDimitry Andric #include "CodeGenFunction.h"
150b57cec5SDimitry Andric #include "CoverageMappingGen.h"
160b57cec5SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
170b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h"
180b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
190b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h"
20480093f4SDimitry Andric #include "llvm/Support/CommandLine.h"
210b57cec5SDimitry Andric #include "llvm/Support/Endian.h"
220b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
230b57cec5SDimitry Andric #include "llvm/Support/MD5.h"
24bdd1243dSDimitry Andric #include <optional>
250b57cec5SDimitry Andric 
26*0fca6ea1SDimitry Andric namespace llvm {
27*0fca6ea1SDimitry Andric extern cl::opt<bool> EnableSingleByteCoverage;
28*0fca6ea1SDimitry Andric } // namespace llvm
29*0fca6ea1SDimitry Andric 
300b57cec5SDimitry Andric static llvm::cl::opt<bool>
3181ad6265SDimitry Andric     EnableValueProfiling("enable-value-profiling",
320b57cec5SDimitry Andric                          llvm::cl::desc("Enable value profiling"),
330b57cec5SDimitry Andric                          llvm::cl::Hidden, llvm::cl::init(false));
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric using namespace clang;
360b57cec5SDimitry Andric using namespace CodeGen;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric void CodeGenPGO::setFuncName(StringRef Name,
390b57cec5SDimitry Andric                              llvm::GlobalValue::LinkageTypes Linkage) {
400b57cec5SDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
410b57cec5SDimitry Andric   FuncName = llvm::getPGOFuncName(
420b57cec5SDimitry Andric       Name, Linkage, CGM.getCodeGenOpts().MainFileName,
430b57cec5SDimitry Andric       PGOReader ? PGOReader->getVersion() : llvm::IndexedInstrProf::Version);
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric   // If we're generating a profile, create a variable for the name.
460b57cec5SDimitry Andric   if (CGM.getCodeGenOpts().hasProfileClangInstr())
470b57cec5SDimitry Andric     FuncNameVar = llvm::createPGOFuncNameVar(CGM.getModule(), Linkage, FuncName);
480b57cec5SDimitry Andric }
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric void CodeGenPGO::setFuncName(llvm::Function *Fn) {
510b57cec5SDimitry Andric   setFuncName(Fn->getName(), Fn->getLinkage());
520b57cec5SDimitry Andric   // Create PGOFuncName meta data.
530b57cec5SDimitry Andric   llvm::createPGOFuncNameMetadata(*Fn, FuncName);
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric /// The version of the PGO hash algorithm.
570b57cec5SDimitry Andric enum PGOHashVersion : unsigned {
580b57cec5SDimitry Andric   PGO_HASH_V1,
590b57cec5SDimitry Andric   PGO_HASH_V2,
605ffd83dbSDimitry Andric   PGO_HASH_V3,
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   // Keep this set to the latest hash version.
635ffd83dbSDimitry Andric   PGO_HASH_LATEST = PGO_HASH_V3
640b57cec5SDimitry Andric };
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric namespace {
670b57cec5SDimitry Andric /// Stable hasher for PGO region counters.
680b57cec5SDimitry Andric ///
690b57cec5SDimitry Andric /// PGOHash produces a stable hash of a given function's control flow.
700b57cec5SDimitry Andric ///
710b57cec5SDimitry Andric /// Changing the output of this hash will invalidate all previously generated
720b57cec5SDimitry Andric /// profiles -- i.e., don't do it.
730b57cec5SDimitry Andric ///
740b57cec5SDimitry Andric /// \note  When this hash does eventually change (years?), we still need to
750b57cec5SDimitry Andric /// support old hashes.  We'll need to pull in the version number from the
760b57cec5SDimitry Andric /// profile data format and use the matching hash function.
770b57cec5SDimitry Andric class PGOHash {
780b57cec5SDimitry Andric   uint64_t Working;
790b57cec5SDimitry Andric   unsigned Count;
800b57cec5SDimitry Andric   PGOHashVersion HashVersion;
810b57cec5SDimitry Andric   llvm::MD5 MD5;
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   static const int NumBitsPerType = 6;
840b57cec5SDimitry Andric   static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
850b57cec5SDimitry Andric   static const unsigned TooBig = 1u << NumBitsPerType;
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric public:
880b57cec5SDimitry Andric   /// Hash values for AST nodes.
890b57cec5SDimitry Andric   ///
900b57cec5SDimitry Andric   /// Distinct values for AST nodes that have region counters attached.
910b57cec5SDimitry Andric   ///
920b57cec5SDimitry Andric   /// These values must be stable.  All new members must be added at the end,
930b57cec5SDimitry Andric   /// and no members should be removed.  Changing the enumeration value for an
940b57cec5SDimitry Andric   /// AST node will affect the hash of every function that contains that node.
950b57cec5SDimitry Andric   enum HashType : unsigned char {
960b57cec5SDimitry Andric     None = 0,
970b57cec5SDimitry Andric     LabelStmt = 1,
980b57cec5SDimitry Andric     WhileStmt,
990b57cec5SDimitry Andric     DoStmt,
1000b57cec5SDimitry Andric     ForStmt,
1010b57cec5SDimitry Andric     CXXForRangeStmt,
1020b57cec5SDimitry Andric     ObjCForCollectionStmt,
1030b57cec5SDimitry Andric     SwitchStmt,
1040b57cec5SDimitry Andric     CaseStmt,
1050b57cec5SDimitry Andric     DefaultStmt,
1060b57cec5SDimitry Andric     IfStmt,
1070b57cec5SDimitry Andric     CXXTryStmt,
1080b57cec5SDimitry Andric     CXXCatchStmt,
1090b57cec5SDimitry Andric     ConditionalOperator,
1100b57cec5SDimitry Andric     BinaryOperatorLAnd,
1110b57cec5SDimitry Andric     BinaryOperatorLOr,
1120b57cec5SDimitry Andric     BinaryConditionalOperator,
1130b57cec5SDimitry Andric     // The preceding values are available with PGO_HASH_V1.
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric     EndOfScope,
1160b57cec5SDimitry Andric     IfThenBranch,
1170b57cec5SDimitry Andric     IfElseBranch,
1180b57cec5SDimitry Andric     GotoStmt,
1190b57cec5SDimitry Andric     IndirectGotoStmt,
1200b57cec5SDimitry Andric     BreakStmt,
1210b57cec5SDimitry Andric     ContinueStmt,
1220b57cec5SDimitry Andric     ReturnStmt,
1230b57cec5SDimitry Andric     ThrowExpr,
1240b57cec5SDimitry Andric     UnaryOperatorLNot,
1250b57cec5SDimitry Andric     BinaryOperatorLT,
1260b57cec5SDimitry Andric     BinaryOperatorGT,
1270b57cec5SDimitry Andric     BinaryOperatorLE,
1280b57cec5SDimitry Andric     BinaryOperatorGE,
1290b57cec5SDimitry Andric     BinaryOperatorEQ,
1300b57cec5SDimitry Andric     BinaryOperatorNE,
1315ffd83dbSDimitry Andric     // The preceding values are available since PGO_HASH_V2.
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric     // Keep this last.  It's for the static assert that follows.
1340b57cec5SDimitry Andric     LastHashType
1350b57cec5SDimitry Andric   };
1360b57cec5SDimitry Andric   static_assert(LastHashType <= TooBig, "Too many types in HashType");
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   PGOHash(PGOHashVersion HashVersion)
13904eeddc0SDimitry Andric       : Working(0), Count(0), HashVersion(HashVersion) {}
1400b57cec5SDimitry Andric   void combine(HashType Type);
1410b57cec5SDimitry Andric   uint64_t finalize();
1420b57cec5SDimitry Andric   PGOHashVersion getHashVersion() const { return HashVersion; }
1430b57cec5SDimitry Andric };
1440b57cec5SDimitry Andric const int PGOHash::NumBitsPerType;
1450b57cec5SDimitry Andric const unsigned PGOHash::NumTypesPerWord;
1460b57cec5SDimitry Andric const unsigned PGOHash::TooBig;
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric /// Get the PGO hash version used in the given indexed profile.
1490b57cec5SDimitry Andric static PGOHashVersion getPGOHashVersion(llvm::IndexedInstrProfReader *PGOReader,
1500b57cec5SDimitry Andric                                         CodeGenModule &CGM) {
1510b57cec5SDimitry Andric   if (PGOReader->getVersion() <= 4)
1520b57cec5SDimitry Andric     return PGO_HASH_V1;
1535ffd83dbSDimitry Andric   if (PGOReader->getVersion() <= 5)
1540b57cec5SDimitry Andric     return PGO_HASH_V2;
1555ffd83dbSDimitry Andric   return PGO_HASH_V3;
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
1590b57cec5SDimitry Andric struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
1600b57cec5SDimitry Andric   using Base = RecursiveASTVisitor<MapRegionCounters>;
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric   /// The next counter value to assign.
1630b57cec5SDimitry Andric   unsigned NextCounter;
1640b57cec5SDimitry Andric   /// The function hash.
1650b57cec5SDimitry Andric   PGOHash Hash;
1660b57cec5SDimitry Andric   /// The map of statements to counters.
1670b57cec5SDimitry Andric   llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
168*0fca6ea1SDimitry Andric   /// The state of MC/DC Coverage in this function.
169*0fca6ea1SDimitry Andric   MCDC::State &MCDCState;
1701db9f3b2SDimitry Andric   /// Maximum number of supported MC/DC conditions in a boolean expression.
1711db9f3b2SDimitry Andric   unsigned MCDCMaxCond;
172e8d8bef9SDimitry Andric   /// The profile version.
173e8d8bef9SDimitry Andric   uint64_t ProfileVersion;
1741db9f3b2SDimitry Andric   /// Diagnostics Engine used to report warnings.
1751db9f3b2SDimitry Andric   DiagnosticsEngine &Diag;
1760b57cec5SDimitry Andric 
177e8d8bef9SDimitry Andric   MapRegionCounters(PGOHashVersion HashVersion, uint64_t ProfileVersion,
1781db9f3b2SDimitry Andric                     llvm::DenseMap<const Stmt *, unsigned> &CounterMap,
179*0fca6ea1SDimitry Andric                     MCDC::State &MCDCState, unsigned MCDCMaxCond,
180*0fca6ea1SDimitry Andric                     DiagnosticsEngine &Diag)
181e8d8bef9SDimitry Andric       : NextCounter(0), Hash(HashVersion), CounterMap(CounterMap),
182*0fca6ea1SDimitry Andric         MCDCState(MCDCState), MCDCMaxCond(MCDCMaxCond),
183*0fca6ea1SDimitry Andric         ProfileVersion(ProfileVersion), Diag(Diag) {}
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   // Blocks and lambdas are handled as separate functions, so we need not
1860b57cec5SDimitry Andric   // traverse them in the parent context.
1870b57cec5SDimitry Andric   bool TraverseBlockExpr(BlockExpr *BE) { return true; }
1880b57cec5SDimitry Andric   bool TraverseLambdaExpr(LambdaExpr *LE) {
1890b57cec5SDimitry Andric     // Traverse the captures, but not the body.
190480093f4SDimitry Andric     for (auto C : zip(LE->captures(), LE->capture_inits()))
1910b57cec5SDimitry Andric       TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
1920b57cec5SDimitry Andric     return true;
1930b57cec5SDimitry Andric   }
1940b57cec5SDimitry Andric   bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   bool VisitDecl(const Decl *D) {
1970b57cec5SDimitry Andric     switch (D->getKind()) {
1980b57cec5SDimitry Andric     default:
1990b57cec5SDimitry Andric       break;
2000b57cec5SDimitry Andric     case Decl::Function:
2010b57cec5SDimitry Andric     case Decl::CXXMethod:
2020b57cec5SDimitry Andric     case Decl::CXXConstructor:
2030b57cec5SDimitry Andric     case Decl::CXXDestructor:
2040b57cec5SDimitry Andric     case Decl::CXXConversion:
2050b57cec5SDimitry Andric     case Decl::ObjCMethod:
2060b57cec5SDimitry Andric     case Decl::Block:
2070b57cec5SDimitry Andric     case Decl::Captured:
2080b57cec5SDimitry Andric       CounterMap[D->getBody()] = NextCounter++;
2090b57cec5SDimitry Andric       break;
2100b57cec5SDimitry Andric     }
2110b57cec5SDimitry Andric     return true;
2120b57cec5SDimitry Andric   }
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   /// If \p S gets a fresh counter, update the counter mappings. Return the
2150b57cec5SDimitry Andric   /// V1 hash of \p S.
2160b57cec5SDimitry Andric   PGOHash::HashType updateCounterMappings(Stmt *S) {
2170b57cec5SDimitry Andric     auto Type = getHashType(PGO_HASH_V1, S);
2180b57cec5SDimitry Andric     if (Type != PGOHash::None)
2190b57cec5SDimitry Andric       CounterMap[S] = NextCounter++;
2200b57cec5SDimitry Andric     return Type;
2210b57cec5SDimitry Andric   }
2220b57cec5SDimitry Andric 
2231db9f3b2SDimitry Andric   /// The following stacks are used with dataTraverseStmtPre() and
2241db9f3b2SDimitry Andric   /// dataTraverseStmtPost() to track the depth of nested logical operators in a
2251db9f3b2SDimitry Andric   /// boolean expression in a function.  The ultimate purpose is to keep track
2261db9f3b2SDimitry Andric   /// of the number of leaf-level conditions in the boolean expression so that a
2271db9f3b2SDimitry Andric   /// profile bitmap can be allocated based on that number.
2281db9f3b2SDimitry Andric   ///
2291db9f3b2SDimitry Andric   /// The stacks are also used to find error cases and notify the user.  A
2301db9f3b2SDimitry Andric   /// standard logical operator nest for a boolean expression could be in a form
2311db9f3b2SDimitry Andric   /// similar to this: "x = a && b && c && (d || f)"
2321db9f3b2SDimitry Andric   unsigned NumCond = 0;
2331db9f3b2SDimitry Andric   bool SplitNestedLogicalOp = false;
2341db9f3b2SDimitry Andric   SmallVector<const Stmt *, 16> NonLogOpStack;
2351db9f3b2SDimitry Andric   SmallVector<const BinaryOperator *, 16> LogOpStack;
2361db9f3b2SDimitry Andric 
2371db9f3b2SDimitry Andric   // Hook: dataTraverseStmtPre() is invoked prior to visiting an AST Stmt node.
2381db9f3b2SDimitry Andric   bool dataTraverseStmtPre(Stmt *S) {
2391db9f3b2SDimitry Andric     /// If MC/DC is not enabled, MCDCMaxCond will be set to 0. Do nothing.
2401db9f3b2SDimitry Andric     if (MCDCMaxCond == 0)
2411db9f3b2SDimitry Andric       return true;
2421db9f3b2SDimitry Andric 
2434c2d3b02SDimitry Andric     /// At the top of the logical operator nest, reset the number of conditions,
2444c2d3b02SDimitry Andric     /// also forget previously seen split nesting cases.
2454c2d3b02SDimitry Andric     if (LogOpStack.empty()) {
2461db9f3b2SDimitry Andric       NumCond = 0;
2474c2d3b02SDimitry Andric       SplitNestedLogicalOp = false;
2484c2d3b02SDimitry Andric     }
2491db9f3b2SDimitry Andric 
2501db9f3b2SDimitry Andric     if (const Expr *E = dyn_cast<Expr>(S)) {
2511db9f3b2SDimitry Andric       const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E->IgnoreParens());
2521db9f3b2SDimitry Andric       if (BinOp && BinOp->isLogicalOp()) {
2531db9f3b2SDimitry Andric         /// Check for "split-nested" logical operators. This happens when a new
2541db9f3b2SDimitry Andric         /// boolean expression logical-op nest is encountered within an existing
2551db9f3b2SDimitry Andric         /// boolean expression, separated by a non-logical operator.  For
2561db9f3b2SDimitry Andric         /// example, in "x = (a && b && c && foo(d && f))", the "d && f" case
2571db9f3b2SDimitry Andric         /// starts a new boolean expression that is separated from the other
2581db9f3b2SDimitry Andric         /// conditions by the operator foo(). Split-nested cases are not
2591db9f3b2SDimitry Andric         /// supported by MC/DC.
2601db9f3b2SDimitry Andric         SplitNestedLogicalOp = SplitNestedLogicalOp || !NonLogOpStack.empty();
2611db9f3b2SDimitry Andric 
2621db9f3b2SDimitry Andric         LogOpStack.push_back(BinOp);
2631db9f3b2SDimitry Andric         return true;
2641db9f3b2SDimitry Andric       }
2651db9f3b2SDimitry Andric     }
2661db9f3b2SDimitry Andric 
2671db9f3b2SDimitry Andric     /// Keep track of non-logical operators. These are OK as long as we don't
2681db9f3b2SDimitry Andric     /// encounter a new logical operator after seeing one.
2691db9f3b2SDimitry Andric     if (!LogOpStack.empty())
2701db9f3b2SDimitry Andric       NonLogOpStack.push_back(S);
2711db9f3b2SDimitry Andric 
2721db9f3b2SDimitry Andric     return true;
2731db9f3b2SDimitry Andric   }
2741db9f3b2SDimitry Andric 
2751db9f3b2SDimitry Andric   // Hook: dataTraverseStmtPost() is invoked by the AST visitor after visiting
2761db9f3b2SDimitry Andric   // an AST Stmt node.  MC/DC will use it to to signal when the top of a
2771db9f3b2SDimitry Andric   // logical operation (boolean expression) nest is encountered.
2781db9f3b2SDimitry Andric   bool dataTraverseStmtPost(Stmt *S) {
2791db9f3b2SDimitry Andric     /// If MC/DC is not enabled, MCDCMaxCond will be set to 0. Do nothing.
2801db9f3b2SDimitry Andric     if (MCDCMaxCond == 0)
2811db9f3b2SDimitry Andric       return true;
2821db9f3b2SDimitry Andric 
2831db9f3b2SDimitry Andric     if (const Expr *E = dyn_cast<Expr>(S)) {
2841db9f3b2SDimitry Andric       const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E->IgnoreParens());
2851db9f3b2SDimitry Andric       if (BinOp && BinOp->isLogicalOp()) {
2861db9f3b2SDimitry Andric         assert(LogOpStack.back() == BinOp);
2871db9f3b2SDimitry Andric         LogOpStack.pop_back();
2881db9f3b2SDimitry Andric 
2891db9f3b2SDimitry Andric         /// At the top of logical operator nest:
2901db9f3b2SDimitry Andric         if (LogOpStack.empty()) {
2911db9f3b2SDimitry Andric           /// Was the "split-nested" logical operator case encountered?
2921db9f3b2SDimitry Andric           if (SplitNestedLogicalOp) {
2931db9f3b2SDimitry Andric             unsigned DiagID = Diag.getCustomDiagID(
2941db9f3b2SDimitry Andric                 DiagnosticsEngine::Warning,
2951db9f3b2SDimitry Andric                 "unsupported MC/DC boolean expression; "
2961db9f3b2SDimitry Andric                 "contains an operation with a nested boolean expression. "
2971db9f3b2SDimitry Andric                 "Expression will not be covered");
2981db9f3b2SDimitry Andric             Diag.Report(S->getBeginLoc(), DiagID);
2994c2d3b02SDimitry Andric             return true;
3001db9f3b2SDimitry Andric           }
3011db9f3b2SDimitry Andric 
3021db9f3b2SDimitry Andric           /// Was the maximum number of conditions encountered?
3031db9f3b2SDimitry Andric           if (NumCond > MCDCMaxCond) {
3041db9f3b2SDimitry Andric             unsigned DiagID = Diag.getCustomDiagID(
3051db9f3b2SDimitry Andric                 DiagnosticsEngine::Warning,
3061db9f3b2SDimitry Andric                 "unsupported MC/DC boolean expression; "
3071db9f3b2SDimitry Andric                 "number of conditions (%0) exceeds max (%1). "
3081db9f3b2SDimitry Andric                 "Expression will not be covered");
3091db9f3b2SDimitry Andric             Diag.Report(S->getBeginLoc(), DiagID) << NumCond << MCDCMaxCond;
3104c2d3b02SDimitry Andric             return true;
3111db9f3b2SDimitry Andric           }
3121db9f3b2SDimitry Andric 
313*0fca6ea1SDimitry Andric           // Otherwise, allocate the Decision.
314*0fca6ea1SDimitry Andric           MCDCState.DecisionByStmt[BinOp].BitmapIdx = 0;
3151db9f3b2SDimitry Andric         }
3161db9f3b2SDimitry Andric         return true;
3171db9f3b2SDimitry Andric       }
3181db9f3b2SDimitry Andric     }
3191db9f3b2SDimitry Andric 
3201db9f3b2SDimitry Andric     if (!LogOpStack.empty())
3211db9f3b2SDimitry Andric       NonLogOpStack.pop_back();
3221db9f3b2SDimitry Andric 
3231db9f3b2SDimitry Andric     return true;
3241db9f3b2SDimitry Andric   }
3251db9f3b2SDimitry Andric 
326e8d8bef9SDimitry Andric   /// The RHS of all logical operators gets a fresh counter in order to count
327e8d8bef9SDimitry Andric   /// how many times the RHS evaluates to true or false, depending on the
328e8d8bef9SDimitry Andric   /// semantics of the operator. This is only valid for ">= v7" of the profile
3291db9f3b2SDimitry Andric   /// version so that we facilitate backward compatibility. In addition, in
3301db9f3b2SDimitry Andric   /// order to use MC/DC, count the number of total LHS and RHS conditions.
331e8d8bef9SDimitry Andric   bool VisitBinaryOperator(BinaryOperator *S) {
3321db9f3b2SDimitry Andric     if (S->isLogicalOp()) {
3331db9f3b2SDimitry Andric       if (CodeGenFunction::isInstrumentedCondition(S->getLHS()))
3341db9f3b2SDimitry Andric         NumCond++;
3351db9f3b2SDimitry Andric 
3361db9f3b2SDimitry Andric       if (CodeGenFunction::isInstrumentedCondition(S->getRHS())) {
337e8d8bef9SDimitry Andric         if (ProfileVersion >= llvm::IndexedInstrProf::Version7)
338e8d8bef9SDimitry Andric           CounterMap[S->getRHS()] = NextCounter++;
3391db9f3b2SDimitry Andric 
3401db9f3b2SDimitry Andric         NumCond++;
3411db9f3b2SDimitry Andric       }
3421db9f3b2SDimitry Andric     }
343e8d8bef9SDimitry Andric     return Base::VisitBinaryOperator(S);
344e8d8bef9SDimitry Andric   }
345e8d8bef9SDimitry Andric 
346*0fca6ea1SDimitry Andric   bool VisitConditionalOperator(ConditionalOperator *S) {
347*0fca6ea1SDimitry Andric     if (llvm::EnableSingleByteCoverage && S->getTrueExpr())
348*0fca6ea1SDimitry Andric       CounterMap[S->getTrueExpr()] = NextCounter++;
349*0fca6ea1SDimitry Andric     if (llvm::EnableSingleByteCoverage && S->getFalseExpr())
350*0fca6ea1SDimitry Andric       CounterMap[S->getFalseExpr()] = NextCounter++;
351*0fca6ea1SDimitry Andric     return Base::VisitConditionalOperator(S);
352*0fca6ea1SDimitry Andric   }
353*0fca6ea1SDimitry Andric 
3540b57cec5SDimitry Andric   /// Include \p S in the function hash.
3550b57cec5SDimitry Andric   bool VisitStmt(Stmt *S) {
3560b57cec5SDimitry Andric     auto Type = updateCounterMappings(S);
3570b57cec5SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
3580b57cec5SDimitry Andric       Type = getHashType(Hash.getHashVersion(), S);
3590b57cec5SDimitry Andric     if (Type != PGOHash::None)
3600b57cec5SDimitry Andric       Hash.combine(Type);
3610b57cec5SDimitry Andric     return true;
3620b57cec5SDimitry Andric   }
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric   bool TraverseIfStmt(IfStmt *If) {
3650b57cec5SDimitry Andric     // If we used the V1 hash, use the default traversal.
3660b57cec5SDimitry Andric     if (Hash.getHashVersion() == PGO_HASH_V1)
3670b57cec5SDimitry Andric       return Base::TraverseIfStmt(If);
3680b57cec5SDimitry Andric 
369*0fca6ea1SDimitry Andric     // When single byte coverage mode is enabled, add a counter to then and
370*0fca6ea1SDimitry Andric     // else.
371*0fca6ea1SDimitry Andric     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
372*0fca6ea1SDimitry Andric     for (Stmt *CS : If->children()) {
373*0fca6ea1SDimitry Andric       if (!CS || NoSingleByteCoverage)
374*0fca6ea1SDimitry Andric         continue;
375*0fca6ea1SDimitry Andric       if (CS == If->getThen())
376*0fca6ea1SDimitry Andric         CounterMap[If->getThen()] = NextCounter++;
377*0fca6ea1SDimitry Andric       else if (CS == If->getElse())
378*0fca6ea1SDimitry Andric         CounterMap[If->getElse()] = NextCounter++;
379*0fca6ea1SDimitry Andric     }
380*0fca6ea1SDimitry Andric 
3810b57cec5SDimitry Andric     // Otherwise, keep track of which branch we're in while traversing.
3820b57cec5SDimitry Andric     VisitStmt(If);
383*0fca6ea1SDimitry Andric 
3840b57cec5SDimitry Andric     for (Stmt *CS : If->children()) {
3850b57cec5SDimitry Andric       if (!CS)
3860b57cec5SDimitry Andric         continue;
3870b57cec5SDimitry Andric       if (CS == If->getThen())
3880b57cec5SDimitry Andric         Hash.combine(PGOHash::IfThenBranch);
3890b57cec5SDimitry Andric       else if (CS == If->getElse())
3900b57cec5SDimitry Andric         Hash.combine(PGOHash::IfElseBranch);
3910b57cec5SDimitry Andric       TraverseStmt(CS);
3920b57cec5SDimitry Andric     }
3930b57cec5SDimitry Andric     Hash.combine(PGOHash::EndOfScope);
3940b57cec5SDimitry Andric     return true;
3950b57cec5SDimitry Andric   }
3960b57cec5SDimitry Andric 
397*0fca6ea1SDimitry Andric   bool TraverseWhileStmt(WhileStmt *While) {
398*0fca6ea1SDimitry Andric     // When single byte coverage mode is enabled, add a counter to condition and
399*0fca6ea1SDimitry Andric     // body.
400*0fca6ea1SDimitry Andric     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
401*0fca6ea1SDimitry Andric     for (Stmt *CS : While->children()) {
402*0fca6ea1SDimitry Andric       if (!CS || NoSingleByteCoverage)
403*0fca6ea1SDimitry Andric         continue;
404*0fca6ea1SDimitry Andric       if (CS == While->getCond())
405*0fca6ea1SDimitry Andric         CounterMap[While->getCond()] = NextCounter++;
406*0fca6ea1SDimitry Andric       else if (CS == While->getBody())
407*0fca6ea1SDimitry Andric         CounterMap[While->getBody()] = NextCounter++;
408*0fca6ea1SDimitry Andric     }
409*0fca6ea1SDimitry Andric 
410*0fca6ea1SDimitry Andric     Base::TraverseWhileStmt(While);
411*0fca6ea1SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
412*0fca6ea1SDimitry Andric       Hash.combine(PGOHash::EndOfScope);
413*0fca6ea1SDimitry Andric     return true;
414*0fca6ea1SDimitry Andric   }
415*0fca6ea1SDimitry Andric 
416*0fca6ea1SDimitry Andric   bool TraverseDoStmt(DoStmt *Do) {
417*0fca6ea1SDimitry Andric     // When single byte coverage mode is enabled, add a counter to condition and
418*0fca6ea1SDimitry Andric     // body.
419*0fca6ea1SDimitry Andric     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
420*0fca6ea1SDimitry Andric     for (Stmt *CS : Do->children()) {
421*0fca6ea1SDimitry Andric       if (!CS || NoSingleByteCoverage)
422*0fca6ea1SDimitry Andric         continue;
423*0fca6ea1SDimitry Andric       if (CS == Do->getCond())
424*0fca6ea1SDimitry Andric         CounterMap[Do->getCond()] = NextCounter++;
425*0fca6ea1SDimitry Andric       else if (CS == Do->getBody())
426*0fca6ea1SDimitry Andric         CounterMap[Do->getBody()] = NextCounter++;
427*0fca6ea1SDimitry Andric     }
428*0fca6ea1SDimitry Andric 
429*0fca6ea1SDimitry Andric     Base::TraverseDoStmt(Do);
430*0fca6ea1SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
431*0fca6ea1SDimitry Andric       Hash.combine(PGOHash::EndOfScope);
432*0fca6ea1SDimitry Andric     return true;
433*0fca6ea1SDimitry Andric   }
434*0fca6ea1SDimitry Andric 
435*0fca6ea1SDimitry Andric   bool TraverseForStmt(ForStmt *For) {
436*0fca6ea1SDimitry Andric     // When single byte coverage mode is enabled, add a counter to condition,
437*0fca6ea1SDimitry Andric     // increment and body.
438*0fca6ea1SDimitry Andric     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
439*0fca6ea1SDimitry Andric     for (Stmt *CS : For->children()) {
440*0fca6ea1SDimitry Andric       if (!CS || NoSingleByteCoverage)
441*0fca6ea1SDimitry Andric         continue;
442*0fca6ea1SDimitry Andric       if (CS == For->getCond())
443*0fca6ea1SDimitry Andric         CounterMap[For->getCond()] = NextCounter++;
444*0fca6ea1SDimitry Andric       else if (CS == For->getInc())
445*0fca6ea1SDimitry Andric         CounterMap[For->getInc()] = NextCounter++;
446*0fca6ea1SDimitry Andric       else if (CS == For->getBody())
447*0fca6ea1SDimitry Andric         CounterMap[For->getBody()] = NextCounter++;
448*0fca6ea1SDimitry Andric     }
449*0fca6ea1SDimitry Andric 
450*0fca6ea1SDimitry Andric     Base::TraverseForStmt(For);
451*0fca6ea1SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
452*0fca6ea1SDimitry Andric       Hash.combine(PGOHash::EndOfScope);
453*0fca6ea1SDimitry Andric     return true;
454*0fca6ea1SDimitry Andric   }
455*0fca6ea1SDimitry Andric 
456*0fca6ea1SDimitry Andric   bool TraverseCXXForRangeStmt(CXXForRangeStmt *ForRange) {
457*0fca6ea1SDimitry Andric     // When single byte coverage mode is enabled, add a counter to body.
458*0fca6ea1SDimitry Andric     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
459*0fca6ea1SDimitry Andric     for (Stmt *CS : ForRange->children()) {
460*0fca6ea1SDimitry Andric       if (!CS || NoSingleByteCoverage)
461*0fca6ea1SDimitry Andric         continue;
462*0fca6ea1SDimitry Andric       if (CS == ForRange->getBody())
463*0fca6ea1SDimitry Andric         CounterMap[ForRange->getBody()] = NextCounter++;
464*0fca6ea1SDimitry Andric     }
465*0fca6ea1SDimitry Andric 
466*0fca6ea1SDimitry Andric     Base::TraverseCXXForRangeStmt(ForRange);
467*0fca6ea1SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
468*0fca6ea1SDimitry Andric       Hash.combine(PGOHash::EndOfScope);
469*0fca6ea1SDimitry Andric     return true;
470*0fca6ea1SDimitry Andric   }
471*0fca6ea1SDimitry Andric 
4720b57cec5SDimitry Andric // If the statement type \p N is nestable, and its nesting impacts profile
4730b57cec5SDimitry Andric // stability, define a custom traversal which tracks the end of the statement
4740b57cec5SDimitry Andric // in the hash (provided we're not using the V1 hash).
4750b57cec5SDimitry Andric #define DEFINE_NESTABLE_TRAVERSAL(N)                                           \
4760b57cec5SDimitry Andric   bool Traverse##N(N *S) {                                                     \
4770b57cec5SDimitry Andric     Base::Traverse##N(S);                                                      \
4780b57cec5SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)                                  \
4790b57cec5SDimitry Andric       Hash.combine(PGOHash::EndOfScope);                                       \
4800b57cec5SDimitry Andric     return true;                                                               \
4810b57cec5SDimitry Andric   }
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(ObjCForCollectionStmt)
4840b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXTryStmt)
4850b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXCatchStmt)
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric   /// Get version \p HashVersion of the PGO hash for \p S.
4880b57cec5SDimitry Andric   PGOHash::HashType getHashType(PGOHashVersion HashVersion, const Stmt *S) {
4890b57cec5SDimitry Andric     switch (S->getStmtClass()) {
4900b57cec5SDimitry Andric     default:
4910b57cec5SDimitry Andric       break;
4920b57cec5SDimitry Andric     case Stmt::LabelStmtClass:
4930b57cec5SDimitry Andric       return PGOHash::LabelStmt;
4940b57cec5SDimitry Andric     case Stmt::WhileStmtClass:
4950b57cec5SDimitry Andric       return PGOHash::WhileStmt;
4960b57cec5SDimitry Andric     case Stmt::DoStmtClass:
4970b57cec5SDimitry Andric       return PGOHash::DoStmt;
4980b57cec5SDimitry Andric     case Stmt::ForStmtClass:
4990b57cec5SDimitry Andric       return PGOHash::ForStmt;
5000b57cec5SDimitry Andric     case Stmt::CXXForRangeStmtClass:
5010b57cec5SDimitry Andric       return PGOHash::CXXForRangeStmt;
5020b57cec5SDimitry Andric     case Stmt::ObjCForCollectionStmtClass:
5030b57cec5SDimitry Andric       return PGOHash::ObjCForCollectionStmt;
5040b57cec5SDimitry Andric     case Stmt::SwitchStmtClass:
5050b57cec5SDimitry Andric       return PGOHash::SwitchStmt;
5060b57cec5SDimitry Andric     case Stmt::CaseStmtClass:
5070b57cec5SDimitry Andric       return PGOHash::CaseStmt;
5080b57cec5SDimitry Andric     case Stmt::DefaultStmtClass:
5090b57cec5SDimitry Andric       return PGOHash::DefaultStmt;
5100b57cec5SDimitry Andric     case Stmt::IfStmtClass:
5110b57cec5SDimitry Andric       return PGOHash::IfStmt;
5120b57cec5SDimitry Andric     case Stmt::CXXTryStmtClass:
5130b57cec5SDimitry Andric       return PGOHash::CXXTryStmt;
5140b57cec5SDimitry Andric     case Stmt::CXXCatchStmtClass:
5150b57cec5SDimitry Andric       return PGOHash::CXXCatchStmt;
5160b57cec5SDimitry Andric     case Stmt::ConditionalOperatorClass:
5170b57cec5SDimitry Andric       return PGOHash::ConditionalOperator;
5180b57cec5SDimitry Andric     case Stmt::BinaryConditionalOperatorClass:
5190b57cec5SDimitry Andric       return PGOHash::BinaryConditionalOperator;
5200b57cec5SDimitry Andric     case Stmt::BinaryOperatorClass: {
5210b57cec5SDimitry Andric       const BinaryOperator *BO = cast<BinaryOperator>(S);
5220b57cec5SDimitry Andric       if (BO->getOpcode() == BO_LAnd)
5230b57cec5SDimitry Andric         return PGOHash::BinaryOperatorLAnd;
5240b57cec5SDimitry Andric       if (BO->getOpcode() == BO_LOr)
5250b57cec5SDimitry Andric         return PGOHash::BinaryOperatorLOr;
5265ffd83dbSDimitry Andric       if (HashVersion >= PGO_HASH_V2) {
5270b57cec5SDimitry Andric         switch (BO->getOpcode()) {
5280b57cec5SDimitry Andric         default:
5290b57cec5SDimitry Andric           break;
5300b57cec5SDimitry Andric         case BO_LT:
5310b57cec5SDimitry Andric           return PGOHash::BinaryOperatorLT;
5320b57cec5SDimitry Andric         case BO_GT:
5330b57cec5SDimitry Andric           return PGOHash::BinaryOperatorGT;
5340b57cec5SDimitry Andric         case BO_LE:
5350b57cec5SDimitry Andric           return PGOHash::BinaryOperatorLE;
5360b57cec5SDimitry Andric         case BO_GE:
5370b57cec5SDimitry Andric           return PGOHash::BinaryOperatorGE;
5380b57cec5SDimitry Andric         case BO_EQ:
5390b57cec5SDimitry Andric           return PGOHash::BinaryOperatorEQ;
5400b57cec5SDimitry Andric         case BO_NE:
5410b57cec5SDimitry Andric           return PGOHash::BinaryOperatorNE;
5420b57cec5SDimitry Andric         }
5430b57cec5SDimitry Andric       }
5440b57cec5SDimitry Andric       break;
5450b57cec5SDimitry Andric     }
5460b57cec5SDimitry Andric     }
5470b57cec5SDimitry Andric 
5485ffd83dbSDimitry Andric     if (HashVersion >= PGO_HASH_V2) {
5490b57cec5SDimitry Andric       switch (S->getStmtClass()) {
5500b57cec5SDimitry Andric       default:
5510b57cec5SDimitry Andric         break;
5520b57cec5SDimitry Andric       case Stmt::GotoStmtClass:
5530b57cec5SDimitry Andric         return PGOHash::GotoStmt;
5540b57cec5SDimitry Andric       case Stmt::IndirectGotoStmtClass:
5550b57cec5SDimitry Andric         return PGOHash::IndirectGotoStmt;
5560b57cec5SDimitry Andric       case Stmt::BreakStmtClass:
5570b57cec5SDimitry Andric         return PGOHash::BreakStmt;
5580b57cec5SDimitry Andric       case Stmt::ContinueStmtClass:
5590b57cec5SDimitry Andric         return PGOHash::ContinueStmt;
5600b57cec5SDimitry Andric       case Stmt::ReturnStmtClass:
5610b57cec5SDimitry Andric         return PGOHash::ReturnStmt;
5620b57cec5SDimitry Andric       case Stmt::CXXThrowExprClass:
5630b57cec5SDimitry Andric         return PGOHash::ThrowExpr;
5640b57cec5SDimitry Andric       case Stmt::UnaryOperatorClass: {
5650b57cec5SDimitry Andric         const UnaryOperator *UO = cast<UnaryOperator>(S);
5660b57cec5SDimitry Andric         if (UO->getOpcode() == UO_LNot)
5670b57cec5SDimitry Andric           return PGOHash::UnaryOperatorLNot;
5680b57cec5SDimitry Andric         break;
5690b57cec5SDimitry Andric       }
5700b57cec5SDimitry Andric       }
5710b57cec5SDimitry Andric     }
5720b57cec5SDimitry Andric 
5730b57cec5SDimitry Andric     return PGOHash::None;
5740b57cec5SDimitry Andric   }
5750b57cec5SDimitry Andric };
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric /// A StmtVisitor that propagates the raw counts through the AST and
5780b57cec5SDimitry Andric /// records the count at statements where the value may change.
5790b57cec5SDimitry Andric struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
5800b57cec5SDimitry Andric   /// PGO state.
5810b57cec5SDimitry Andric   CodeGenPGO &PGO;
5820b57cec5SDimitry Andric 
5830b57cec5SDimitry Andric   /// A flag that is set when the current count should be recorded on the
5840b57cec5SDimitry Andric   /// next statement, such as at the exit of a loop.
5850b57cec5SDimitry Andric   bool RecordNextStmtCount;
5860b57cec5SDimitry Andric 
5870b57cec5SDimitry Andric   /// The count at the current location in the traversal.
5880b57cec5SDimitry Andric   uint64_t CurrentCount;
5890b57cec5SDimitry Andric 
5900b57cec5SDimitry Andric   /// The map of statements to count values.
5910b57cec5SDimitry Andric   llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric   /// BreakContinueStack - Keep counts of breaks and continues inside loops.
5940b57cec5SDimitry Andric   struct BreakContinue {
5955f757f3fSDimitry Andric     uint64_t BreakCount = 0;
5965f757f3fSDimitry Andric     uint64_t ContinueCount = 0;
5975f757f3fSDimitry Andric     BreakContinue() = default;
5980b57cec5SDimitry Andric   };
5990b57cec5SDimitry Andric   SmallVector<BreakContinue, 8> BreakContinueStack;
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric   ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
6020b57cec5SDimitry Andric                       CodeGenPGO &PGO)
6030b57cec5SDimitry Andric       : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
6040b57cec5SDimitry Andric 
6050b57cec5SDimitry Andric   void RecordStmtCount(const Stmt *S) {
6060b57cec5SDimitry Andric     if (RecordNextStmtCount) {
6070b57cec5SDimitry Andric       CountMap[S] = CurrentCount;
6080b57cec5SDimitry Andric       RecordNextStmtCount = false;
6090b57cec5SDimitry Andric     }
6100b57cec5SDimitry Andric   }
6110b57cec5SDimitry Andric 
6120b57cec5SDimitry Andric   /// Set and return the current count.
6130b57cec5SDimitry Andric   uint64_t setCount(uint64_t Count) {
6140b57cec5SDimitry Andric     CurrentCount = Count;
6150b57cec5SDimitry Andric     return Count;
6160b57cec5SDimitry Andric   }
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric   void VisitStmt(const Stmt *S) {
6190b57cec5SDimitry Andric     RecordStmtCount(S);
6200b57cec5SDimitry Andric     for (const Stmt *Child : S->children())
6210b57cec5SDimitry Andric       if (Child)
6220b57cec5SDimitry Andric         this->Visit(Child);
6230b57cec5SDimitry Andric   }
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric   void VisitFunctionDecl(const FunctionDecl *D) {
6260b57cec5SDimitry Andric     // Counter tracks entry to the function body.
6270b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
6280b57cec5SDimitry Andric     CountMap[D->getBody()] = BodyCount;
6290b57cec5SDimitry Andric     Visit(D->getBody());
6300b57cec5SDimitry Andric   }
6310b57cec5SDimitry Andric 
6320b57cec5SDimitry Andric   // Skip lambda expressions. We visit these as FunctionDecls when we're
6330b57cec5SDimitry Andric   // generating them and aren't interested in the body when generating a
6340b57cec5SDimitry Andric   // parent context.
6350b57cec5SDimitry Andric   void VisitLambdaExpr(const LambdaExpr *LE) {}
6360b57cec5SDimitry Andric 
6370b57cec5SDimitry Andric   void VisitCapturedDecl(const CapturedDecl *D) {
6380b57cec5SDimitry Andric     // Counter tracks entry to the capture body.
6390b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
6400b57cec5SDimitry Andric     CountMap[D->getBody()] = BodyCount;
6410b57cec5SDimitry Andric     Visit(D->getBody());
6420b57cec5SDimitry Andric   }
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric   void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
6450b57cec5SDimitry Andric     // Counter tracks entry to the method body.
6460b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
6470b57cec5SDimitry Andric     CountMap[D->getBody()] = BodyCount;
6480b57cec5SDimitry Andric     Visit(D->getBody());
6490b57cec5SDimitry Andric   }
6500b57cec5SDimitry Andric 
6510b57cec5SDimitry Andric   void VisitBlockDecl(const BlockDecl *D) {
6520b57cec5SDimitry Andric     // Counter tracks entry to the block body.
6530b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
6540b57cec5SDimitry Andric     CountMap[D->getBody()] = BodyCount;
6550b57cec5SDimitry Andric     Visit(D->getBody());
6560b57cec5SDimitry Andric   }
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric   void VisitReturnStmt(const ReturnStmt *S) {
6590b57cec5SDimitry Andric     RecordStmtCount(S);
6600b57cec5SDimitry Andric     if (S->getRetValue())
6610b57cec5SDimitry Andric       Visit(S->getRetValue());
6620b57cec5SDimitry Andric     CurrentCount = 0;
6630b57cec5SDimitry Andric     RecordNextStmtCount = true;
6640b57cec5SDimitry Andric   }
6650b57cec5SDimitry Andric 
6660b57cec5SDimitry Andric   void VisitCXXThrowExpr(const CXXThrowExpr *E) {
6670b57cec5SDimitry Andric     RecordStmtCount(E);
6680b57cec5SDimitry Andric     if (E->getSubExpr())
6690b57cec5SDimitry Andric       Visit(E->getSubExpr());
6700b57cec5SDimitry Andric     CurrentCount = 0;
6710b57cec5SDimitry Andric     RecordNextStmtCount = true;
6720b57cec5SDimitry Andric   }
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric   void VisitGotoStmt(const GotoStmt *S) {
6750b57cec5SDimitry Andric     RecordStmtCount(S);
6760b57cec5SDimitry Andric     CurrentCount = 0;
6770b57cec5SDimitry Andric     RecordNextStmtCount = true;
6780b57cec5SDimitry Andric   }
6790b57cec5SDimitry Andric 
6800b57cec5SDimitry Andric   void VisitLabelStmt(const LabelStmt *S) {
6810b57cec5SDimitry Andric     RecordNextStmtCount = false;
6820b57cec5SDimitry Andric     // Counter tracks the block following the label.
6830b57cec5SDimitry Andric     uint64_t BlockCount = setCount(PGO.getRegionCount(S));
6840b57cec5SDimitry Andric     CountMap[S] = BlockCount;
6850b57cec5SDimitry Andric     Visit(S->getSubStmt());
6860b57cec5SDimitry Andric   }
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   void VisitBreakStmt(const BreakStmt *S) {
6890b57cec5SDimitry Andric     RecordStmtCount(S);
6900b57cec5SDimitry Andric     assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
6910b57cec5SDimitry Andric     BreakContinueStack.back().BreakCount += CurrentCount;
6920b57cec5SDimitry Andric     CurrentCount = 0;
6930b57cec5SDimitry Andric     RecordNextStmtCount = true;
6940b57cec5SDimitry Andric   }
6950b57cec5SDimitry Andric 
6960b57cec5SDimitry Andric   void VisitContinueStmt(const ContinueStmt *S) {
6970b57cec5SDimitry Andric     RecordStmtCount(S);
6980b57cec5SDimitry Andric     assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
6990b57cec5SDimitry Andric     BreakContinueStack.back().ContinueCount += CurrentCount;
7000b57cec5SDimitry Andric     CurrentCount = 0;
7010b57cec5SDimitry Andric     RecordNextStmtCount = true;
7020b57cec5SDimitry Andric   }
7030b57cec5SDimitry Andric 
7040b57cec5SDimitry Andric   void VisitWhileStmt(const WhileStmt *S) {
7050b57cec5SDimitry Andric     RecordStmtCount(S);
7060b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
7070b57cec5SDimitry Andric 
7080b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
7090b57cec5SDimitry Andric     // Visit the body region first so the break/continue adjustments can be
7100b57cec5SDimitry Andric     // included when visiting the condition.
7110b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
7120b57cec5SDimitry Andric     CountMap[S->getBody()] = CurrentCount;
7130b57cec5SDimitry Andric     Visit(S->getBody());
7140b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
7150b57cec5SDimitry Andric 
7160b57cec5SDimitry Andric     // ...then go back and propagate counts through the condition. The count
7170b57cec5SDimitry Andric     // at the start of the condition is the sum of the incoming edges,
7180b57cec5SDimitry Andric     // the backedge from the end of the loop body, and the edges from
7190b57cec5SDimitry Andric     // continue statements.
7200b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
7210b57cec5SDimitry Andric     uint64_t CondCount =
7220b57cec5SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
7230b57cec5SDimitry Andric     CountMap[S->getCond()] = CondCount;
7240b57cec5SDimitry Andric     Visit(S->getCond());
7250b57cec5SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
7260b57cec5SDimitry Andric     RecordNextStmtCount = true;
7270b57cec5SDimitry Andric   }
7280b57cec5SDimitry Andric 
7290b57cec5SDimitry Andric   void VisitDoStmt(const DoStmt *S) {
7300b57cec5SDimitry Andric     RecordStmtCount(S);
7310b57cec5SDimitry Andric     uint64_t LoopCount = PGO.getRegionCount(S);
7320b57cec5SDimitry Andric 
7330b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
7340b57cec5SDimitry Andric     // The count doesn't include the fallthrough from the parent scope. Add it.
7350b57cec5SDimitry Andric     uint64_t BodyCount = setCount(LoopCount + CurrentCount);
7360b57cec5SDimitry Andric     CountMap[S->getBody()] = BodyCount;
7370b57cec5SDimitry Andric     Visit(S->getBody());
7380b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
7390b57cec5SDimitry Andric 
7400b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
7410b57cec5SDimitry Andric     // The count at the start of the condition is equal to the count at the
7420b57cec5SDimitry Andric     // end of the body, plus any continues.
7430b57cec5SDimitry Andric     uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount);
7440b57cec5SDimitry Andric     CountMap[S->getCond()] = CondCount;
7450b57cec5SDimitry Andric     Visit(S->getCond());
7460b57cec5SDimitry Andric     setCount(BC.BreakCount + CondCount - LoopCount);
7470b57cec5SDimitry Andric     RecordNextStmtCount = true;
7480b57cec5SDimitry Andric   }
7490b57cec5SDimitry Andric 
7500b57cec5SDimitry Andric   void VisitForStmt(const ForStmt *S) {
7510b57cec5SDimitry Andric     RecordStmtCount(S);
7520b57cec5SDimitry Andric     if (S->getInit())
7530b57cec5SDimitry Andric       Visit(S->getInit());
7540b57cec5SDimitry Andric 
7550b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
7560b57cec5SDimitry Andric 
7570b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
7580b57cec5SDimitry Andric     // Visit the body region first. (This is basically the same as a while
7590b57cec5SDimitry Andric     // loop; see further comments in VisitWhileStmt.)
7600b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
7610b57cec5SDimitry Andric     CountMap[S->getBody()] = BodyCount;
7620b57cec5SDimitry Andric     Visit(S->getBody());
7630b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
7640b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
7650b57cec5SDimitry Andric 
7660b57cec5SDimitry Andric     // The increment is essentially part of the body but it needs to include
7670b57cec5SDimitry Andric     // the count for all the continue statements.
7680b57cec5SDimitry Andric     if (S->getInc()) {
7690b57cec5SDimitry Andric       uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
7700b57cec5SDimitry Andric       CountMap[S->getInc()] = IncCount;
7710b57cec5SDimitry Andric       Visit(S->getInc());
7720b57cec5SDimitry Andric     }
7730b57cec5SDimitry Andric 
7740b57cec5SDimitry Andric     // ...then go back and propagate counts through the condition.
7750b57cec5SDimitry Andric     uint64_t CondCount =
7760b57cec5SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
7770b57cec5SDimitry Andric     if (S->getCond()) {
7780b57cec5SDimitry Andric       CountMap[S->getCond()] = CondCount;
7790b57cec5SDimitry Andric       Visit(S->getCond());
7800b57cec5SDimitry Andric     }
7810b57cec5SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
7820b57cec5SDimitry Andric     RecordNextStmtCount = true;
7830b57cec5SDimitry Andric   }
7840b57cec5SDimitry Andric 
7850b57cec5SDimitry Andric   void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
7860b57cec5SDimitry Andric     RecordStmtCount(S);
7870b57cec5SDimitry Andric     if (S->getInit())
7880b57cec5SDimitry Andric       Visit(S->getInit());
7890b57cec5SDimitry Andric     Visit(S->getLoopVarStmt());
7900b57cec5SDimitry Andric     Visit(S->getRangeStmt());
7910b57cec5SDimitry Andric     Visit(S->getBeginStmt());
7920b57cec5SDimitry Andric     Visit(S->getEndStmt());
7930b57cec5SDimitry Andric 
7940b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
7950b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
7960b57cec5SDimitry Andric     // Visit the body region first. (This is basically the same as a while
7970b57cec5SDimitry Andric     // loop; see further comments in VisitWhileStmt.)
7980b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
7990b57cec5SDimitry Andric     CountMap[S->getBody()] = BodyCount;
8000b57cec5SDimitry Andric     Visit(S->getBody());
8010b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
8020b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
8030b57cec5SDimitry Andric 
8040b57cec5SDimitry Andric     // The increment is essentially part of the body but it needs to include
8050b57cec5SDimitry Andric     // the count for all the continue statements.
8060b57cec5SDimitry Andric     uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
8070b57cec5SDimitry Andric     CountMap[S->getInc()] = IncCount;
8080b57cec5SDimitry Andric     Visit(S->getInc());
8090b57cec5SDimitry Andric 
8100b57cec5SDimitry Andric     // ...then go back and propagate counts through the condition.
8110b57cec5SDimitry Andric     uint64_t CondCount =
8120b57cec5SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
8130b57cec5SDimitry Andric     CountMap[S->getCond()] = CondCount;
8140b57cec5SDimitry Andric     Visit(S->getCond());
8150b57cec5SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
8160b57cec5SDimitry Andric     RecordNextStmtCount = true;
8170b57cec5SDimitry Andric   }
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
8200b57cec5SDimitry Andric     RecordStmtCount(S);
8210b57cec5SDimitry Andric     Visit(S->getElement());
8220b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
8230b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
8240b57cec5SDimitry Andric     // Counter tracks the body of the loop.
8250b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
8260b57cec5SDimitry Andric     CountMap[S->getBody()] = BodyCount;
8270b57cec5SDimitry Andric     Visit(S->getBody());
8280b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
8290b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
8300b57cec5SDimitry Andric 
8310b57cec5SDimitry Andric     setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount -
8320b57cec5SDimitry Andric              BodyCount);
8330b57cec5SDimitry Andric     RecordNextStmtCount = true;
8340b57cec5SDimitry Andric   }
8350b57cec5SDimitry Andric 
8360b57cec5SDimitry Andric   void VisitSwitchStmt(const SwitchStmt *S) {
8370b57cec5SDimitry Andric     RecordStmtCount(S);
8380b57cec5SDimitry Andric     if (S->getInit())
8390b57cec5SDimitry Andric       Visit(S->getInit());
8400b57cec5SDimitry Andric     Visit(S->getCond());
8410b57cec5SDimitry Andric     CurrentCount = 0;
8420b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
8430b57cec5SDimitry Andric     Visit(S->getBody());
8440b57cec5SDimitry Andric     // If the switch is inside a loop, add the continue counts.
8450b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
8460b57cec5SDimitry Andric     if (!BreakContinueStack.empty())
8470b57cec5SDimitry Andric       BreakContinueStack.back().ContinueCount += BC.ContinueCount;
8480b57cec5SDimitry Andric     // Counter tracks the exit block of the switch.
8490b57cec5SDimitry Andric     setCount(PGO.getRegionCount(S));
8500b57cec5SDimitry Andric     RecordNextStmtCount = true;
8510b57cec5SDimitry Andric   }
8520b57cec5SDimitry Andric 
8530b57cec5SDimitry Andric   void VisitSwitchCase(const SwitchCase *S) {
8540b57cec5SDimitry Andric     RecordNextStmtCount = false;
8550b57cec5SDimitry Andric     // Counter for this particular case. This counts only jumps from the
8560b57cec5SDimitry Andric     // switch header and does not include fallthrough from the case before
8570b57cec5SDimitry Andric     // this one.
8580b57cec5SDimitry Andric     uint64_t CaseCount = PGO.getRegionCount(S);
8590b57cec5SDimitry Andric     setCount(CurrentCount + CaseCount);
8600b57cec5SDimitry Andric     // We need the count without fallthrough in the mapping, so it's more useful
8610b57cec5SDimitry Andric     // for branch probabilities.
8620b57cec5SDimitry Andric     CountMap[S] = CaseCount;
8630b57cec5SDimitry Andric     RecordNextStmtCount = true;
8640b57cec5SDimitry Andric     Visit(S->getSubStmt());
8650b57cec5SDimitry Andric   }
8660b57cec5SDimitry Andric 
8670b57cec5SDimitry Andric   void VisitIfStmt(const IfStmt *S) {
8680b57cec5SDimitry Andric     RecordStmtCount(S);
869349cc55cSDimitry Andric 
870349cc55cSDimitry Andric     if (S->isConsteval()) {
871349cc55cSDimitry Andric       const Stmt *Stm = S->isNegatedConsteval() ? S->getThen() : S->getElse();
872349cc55cSDimitry Andric       if (Stm)
873349cc55cSDimitry Andric         Visit(Stm);
874349cc55cSDimitry Andric       return;
875349cc55cSDimitry Andric     }
876349cc55cSDimitry Andric 
8770b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
8780b57cec5SDimitry Andric     if (S->getInit())
8790b57cec5SDimitry Andric       Visit(S->getInit());
8800b57cec5SDimitry Andric     Visit(S->getCond());
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric     // Counter tracks the "then" part of an if statement. The count for
8830b57cec5SDimitry Andric     // the "else" part, if it exists, will be calculated from this counter.
8840b57cec5SDimitry Andric     uint64_t ThenCount = setCount(PGO.getRegionCount(S));
8850b57cec5SDimitry Andric     CountMap[S->getThen()] = ThenCount;
8860b57cec5SDimitry Andric     Visit(S->getThen());
8870b57cec5SDimitry Andric     uint64_t OutCount = CurrentCount;
8880b57cec5SDimitry Andric 
8890b57cec5SDimitry Andric     uint64_t ElseCount = ParentCount - ThenCount;
8900b57cec5SDimitry Andric     if (S->getElse()) {
8910b57cec5SDimitry Andric       setCount(ElseCount);
8920b57cec5SDimitry Andric       CountMap[S->getElse()] = ElseCount;
8930b57cec5SDimitry Andric       Visit(S->getElse());
8940b57cec5SDimitry Andric       OutCount += CurrentCount;
8950b57cec5SDimitry Andric     } else
8960b57cec5SDimitry Andric       OutCount += ElseCount;
8970b57cec5SDimitry Andric     setCount(OutCount);
8980b57cec5SDimitry Andric     RecordNextStmtCount = true;
8990b57cec5SDimitry Andric   }
9000b57cec5SDimitry Andric 
9010b57cec5SDimitry Andric   void VisitCXXTryStmt(const CXXTryStmt *S) {
9020b57cec5SDimitry Andric     RecordStmtCount(S);
9030b57cec5SDimitry Andric     Visit(S->getTryBlock());
9040b57cec5SDimitry Andric     for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
9050b57cec5SDimitry Andric       Visit(S->getHandler(I));
9060b57cec5SDimitry Andric     // Counter tracks the continuation block of the try statement.
9070b57cec5SDimitry Andric     setCount(PGO.getRegionCount(S));
9080b57cec5SDimitry Andric     RecordNextStmtCount = true;
9090b57cec5SDimitry Andric   }
9100b57cec5SDimitry Andric 
9110b57cec5SDimitry Andric   void VisitCXXCatchStmt(const CXXCatchStmt *S) {
9120b57cec5SDimitry Andric     RecordNextStmtCount = false;
9130b57cec5SDimitry Andric     // Counter tracks the catch statement's handler block.
9140b57cec5SDimitry Andric     uint64_t CatchCount = setCount(PGO.getRegionCount(S));
9150b57cec5SDimitry Andric     CountMap[S] = CatchCount;
9160b57cec5SDimitry Andric     Visit(S->getHandlerBlock());
9170b57cec5SDimitry Andric   }
9180b57cec5SDimitry Andric 
9190b57cec5SDimitry Andric   void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
9200b57cec5SDimitry Andric     RecordStmtCount(E);
9210b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
9220b57cec5SDimitry Andric     Visit(E->getCond());
9230b57cec5SDimitry Andric 
9240b57cec5SDimitry Andric     // Counter tracks the "true" part of a conditional operator. The
9250b57cec5SDimitry Andric     // count in the "false" part will be calculated from this counter.
9260b57cec5SDimitry Andric     uint64_t TrueCount = setCount(PGO.getRegionCount(E));
9270b57cec5SDimitry Andric     CountMap[E->getTrueExpr()] = TrueCount;
9280b57cec5SDimitry Andric     Visit(E->getTrueExpr());
9290b57cec5SDimitry Andric     uint64_t OutCount = CurrentCount;
9300b57cec5SDimitry Andric 
9310b57cec5SDimitry Andric     uint64_t FalseCount = setCount(ParentCount - TrueCount);
9320b57cec5SDimitry Andric     CountMap[E->getFalseExpr()] = FalseCount;
9330b57cec5SDimitry Andric     Visit(E->getFalseExpr());
9340b57cec5SDimitry Andric     OutCount += CurrentCount;
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric     setCount(OutCount);
9370b57cec5SDimitry Andric     RecordNextStmtCount = true;
9380b57cec5SDimitry Andric   }
9390b57cec5SDimitry Andric 
9400b57cec5SDimitry Andric   void VisitBinLAnd(const BinaryOperator *E) {
9410b57cec5SDimitry Andric     RecordStmtCount(E);
9420b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
9430b57cec5SDimitry Andric     Visit(E->getLHS());
9440b57cec5SDimitry Andric     // Counter tracks the right hand side of a logical and operator.
9450b57cec5SDimitry Andric     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
9460b57cec5SDimitry Andric     CountMap[E->getRHS()] = RHSCount;
9470b57cec5SDimitry Andric     Visit(E->getRHS());
9480b57cec5SDimitry Andric     setCount(ParentCount + RHSCount - CurrentCount);
9490b57cec5SDimitry Andric     RecordNextStmtCount = true;
9500b57cec5SDimitry Andric   }
9510b57cec5SDimitry Andric 
9520b57cec5SDimitry Andric   void VisitBinLOr(const BinaryOperator *E) {
9530b57cec5SDimitry Andric     RecordStmtCount(E);
9540b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
9550b57cec5SDimitry Andric     Visit(E->getLHS());
9560b57cec5SDimitry Andric     // Counter tracks the right hand side of a logical or operator.
9570b57cec5SDimitry Andric     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
9580b57cec5SDimitry Andric     CountMap[E->getRHS()] = RHSCount;
9590b57cec5SDimitry Andric     Visit(E->getRHS());
9600b57cec5SDimitry Andric     setCount(ParentCount + RHSCount - CurrentCount);
9610b57cec5SDimitry Andric     RecordNextStmtCount = true;
9620b57cec5SDimitry Andric   }
9630b57cec5SDimitry Andric };
9640b57cec5SDimitry Andric } // end anonymous namespace
9650b57cec5SDimitry Andric 
9660b57cec5SDimitry Andric void PGOHash::combine(HashType Type) {
9670b57cec5SDimitry Andric   // Check that we never combine 0 and only have six bits.
9680b57cec5SDimitry Andric   assert(Type && "Hash is invalid: unexpected type 0");
9690b57cec5SDimitry Andric   assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
9700b57cec5SDimitry Andric 
9710b57cec5SDimitry Andric   // Pass through MD5 if enough work has built up.
9720b57cec5SDimitry Andric   if (Count && Count % NumTypesPerWord == 0) {
9730b57cec5SDimitry Andric     using namespace llvm::support;
9745f757f3fSDimitry Andric     uint64_t Swapped =
9755f757f3fSDimitry Andric         endian::byte_swap<uint64_t, llvm::endianness::little>(Working);
976bdd1243dSDimitry Andric     MD5.update(llvm::ArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
9770b57cec5SDimitry Andric     Working = 0;
9780b57cec5SDimitry Andric   }
9790b57cec5SDimitry Andric 
9800b57cec5SDimitry Andric   // Accumulate the current type.
9810b57cec5SDimitry Andric   ++Count;
9820b57cec5SDimitry Andric   Working = Working << NumBitsPerType | Type;
9830b57cec5SDimitry Andric }
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric uint64_t PGOHash::finalize() {
9860b57cec5SDimitry Andric   // Use Working as the hash directly if we never used MD5.
9870b57cec5SDimitry Andric   if (Count <= NumTypesPerWord)
9880b57cec5SDimitry Andric     // No need to byte swap here, since none of the math was endian-dependent.
9890b57cec5SDimitry Andric     // This number will be byte-swapped as required on endianness transitions,
9900b57cec5SDimitry Andric     // so we will see the same value on the other side.
9910b57cec5SDimitry Andric     return Working;
9920b57cec5SDimitry Andric 
9930b57cec5SDimitry Andric   // Check for remaining work in Working.
9945ffd83dbSDimitry Andric   if (Working) {
9955ffd83dbSDimitry Andric     // Keep the buggy behavior from v1 and v2 for backward-compatibility. This
9965ffd83dbSDimitry Andric     // is buggy because it converts a uint64_t into an array of uint8_t.
9975ffd83dbSDimitry Andric     if (HashVersion < PGO_HASH_V3) {
9985ffd83dbSDimitry Andric       MD5.update({(uint8_t)Working});
9995ffd83dbSDimitry Andric     } else {
10005ffd83dbSDimitry Andric       using namespace llvm::support;
10015f757f3fSDimitry Andric       uint64_t Swapped =
10025f757f3fSDimitry Andric           endian::byte_swap<uint64_t, llvm::endianness::little>(Working);
1003bdd1243dSDimitry Andric       MD5.update(llvm::ArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
10045ffd83dbSDimitry Andric     }
10055ffd83dbSDimitry Andric   }
10060b57cec5SDimitry Andric 
10070b57cec5SDimitry Andric   // Finalize the MD5 and return the hash.
10080b57cec5SDimitry Andric   llvm::MD5::MD5Result Result;
10090b57cec5SDimitry Andric   MD5.final(Result);
10100b57cec5SDimitry Andric   return Result.low();
10110b57cec5SDimitry Andric }
10120b57cec5SDimitry Andric 
10130b57cec5SDimitry Andric void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
10140b57cec5SDimitry Andric   const Decl *D = GD.getDecl();
10150b57cec5SDimitry Andric   if (!D->hasBody())
10160b57cec5SDimitry Andric     return;
10170b57cec5SDimitry Andric 
1018e8d8bef9SDimitry Andric   // Skip CUDA/HIP kernel launch stub functions.
1019e8d8bef9SDimitry Andric   if (CGM.getLangOpts().CUDA && !CGM.getLangOpts().CUDAIsDevice &&
1020e8d8bef9SDimitry Andric       D->hasAttr<CUDAGlobalAttr>())
1021e8d8bef9SDimitry Andric     return;
1022e8d8bef9SDimitry Andric 
10230b57cec5SDimitry Andric   bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
10240b57cec5SDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
10250b57cec5SDimitry Andric   if (!InstrumentRegions && !PGOReader)
10260b57cec5SDimitry Andric     return;
10270b57cec5SDimitry Andric   if (D->isImplicit())
10280b57cec5SDimitry Andric     return;
10290b57cec5SDimitry Andric   // Constructors and destructors may be represented by several functions in IR.
10300b57cec5SDimitry Andric   // If so, instrument only base variant, others are implemented by delegation
10310b57cec5SDimitry Andric   // to the base one, it would be counted twice otherwise.
10320b57cec5SDimitry Andric   if (CGM.getTarget().getCXXABI().hasConstructorVariants()) {
10330b57cec5SDimitry Andric     if (const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
10340b57cec5SDimitry Andric       if (GD.getCtorType() != Ctor_Base &&
10350b57cec5SDimitry Andric           CodeGenFunction::IsConstructorDelegationValid(CCD))
10360b57cec5SDimitry Andric         return;
10370b57cec5SDimitry Andric   }
10380b57cec5SDimitry Andric   if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
10390b57cec5SDimitry Andric     return;
10400b57cec5SDimitry Andric 
1041fe6060f1SDimitry Andric   CGM.ClearUnusedCoverageMapping(D);
1042e8d8bef9SDimitry Andric   if (Fn->hasFnAttribute(llvm::Attribute::NoProfile))
1043e8d8bef9SDimitry Andric     return;
1044bdd1243dSDimitry Andric   if (Fn->hasFnAttribute(llvm::Attribute::SkipProfile))
1045bdd1243dSDimitry Andric     return;
1046e8d8bef9SDimitry Andric 
1047*0fca6ea1SDimitry Andric   SourceManager &SM = CGM.getContext().getSourceManager();
1048*0fca6ea1SDimitry Andric   if (!llvm::coverage::SystemHeadersCoverage &&
1049*0fca6ea1SDimitry Andric       SM.isInSystemHeader(D->getLocation()))
1050*0fca6ea1SDimitry Andric     return;
1051*0fca6ea1SDimitry Andric 
10520b57cec5SDimitry Andric   setFuncName(Fn);
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric   mapRegionCounters(D);
10550b57cec5SDimitry Andric   if (CGM.getCodeGenOpts().CoverageMapping)
10560b57cec5SDimitry Andric     emitCounterRegionMapping(D);
10570b57cec5SDimitry Andric   if (PGOReader) {
10580b57cec5SDimitry Andric     loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
10590b57cec5SDimitry Andric     computeRegionCounts(D);
10600b57cec5SDimitry Andric     applyFunctionAttributes(PGOReader, Fn);
10610b57cec5SDimitry Andric   }
10620b57cec5SDimitry Andric }
10630b57cec5SDimitry Andric 
10640b57cec5SDimitry Andric void CodeGenPGO::mapRegionCounters(const Decl *D) {
10650b57cec5SDimitry Andric   // Use the latest hash version when inserting instrumentation, but use the
10660b57cec5SDimitry Andric   // version in the indexed profile if we're reading PGO data.
10670b57cec5SDimitry Andric   PGOHashVersion HashVersion = PGO_HASH_LATEST;
1068e8d8bef9SDimitry Andric   uint64_t ProfileVersion = llvm::IndexedInstrProf::Version;
1069e8d8bef9SDimitry Andric   if (auto *PGOReader = CGM.getPGOReader()) {
10700b57cec5SDimitry Andric     HashVersion = getPGOHashVersion(PGOReader, CGM);
1071e8d8bef9SDimitry Andric     ProfileVersion = PGOReader->getVersion();
1072e8d8bef9SDimitry Andric   }
10730b57cec5SDimitry Andric 
10741db9f3b2SDimitry Andric   // If MC/DC is enabled, set the MaxConditions to a preset value. Otherwise,
10751db9f3b2SDimitry Andric   // set it to zero. This value impacts the number of conditions accepted in a
10761db9f3b2SDimitry Andric   // given boolean expression, which impacts the size of the bitmap used to
10771db9f3b2SDimitry Andric   // track test vector execution for that boolean expression.  Because the
10781db9f3b2SDimitry Andric   // bitmap scales exponentially (2^n) based on the number of conditions seen,
10791db9f3b2SDimitry Andric   // the maximum value is hard-coded at 6 conditions, which is more than enough
10801db9f3b2SDimitry Andric   // for most embedded applications. Setting a maximum value prevents the
10811db9f3b2SDimitry Andric   // bitmap footprint from growing too large without the user's knowledge. In
10821db9f3b2SDimitry Andric   // the future, this value could be adjusted with a command-line option.
1083*0fca6ea1SDimitry Andric   unsigned MCDCMaxConditions =
1084*0fca6ea1SDimitry Andric       (CGM.getCodeGenOpts().MCDCCoverage ? CGM.getCodeGenOpts().MCDCMaxConds
1085*0fca6ea1SDimitry Andric                                          : 0);
10861db9f3b2SDimitry Andric 
10870b57cec5SDimitry Andric   RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
1088*0fca6ea1SDimitry Andric   RegionMCDCState.reset(new MCDC::State);
10891db9f3b2SDimitry Andric   MapRegionCounters Walker(HashVersion, ProfileVersion, *RegionCounterMap,
1090*0fca6ea1SDimitry Andric                            *RegionMCDCState, MCDCMaxConditions, CGM.getDiags());
10910b57cec5SDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
10920b57cec5SDimitry Andric     Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
10930b57cec5SDimitry Andric   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
10940b57cec5SDimitry Andric     Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
10950b57cec5SDimitry Andric   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
10960b57cec5SDimitry Andric     Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
10970b57cec5SDimitry Andric   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
10980b57cec5SDimitry Andric     Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
10990b57cec5SDimitry Andric   assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
11000b57cec5SDimitry Andric   NumRegionCounters = Walker.NextCounter;
11010b57cec5SDimitry Andric   FunctionHash = Walker.Hash.finalize();
11020b57cec5SDimitry Andric }
11030b57cec5SDimitry Andric 
11040b57cec5SDimitry Andric bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) {
11050b57cec5SDimitry Andric   if (!D->getBody())
11060b57cec5SDimitry Andric     return true;
11070b57cec5SDimitry Andric 
1108e8d8bef9SDimitry Andric   // Skip host-only functions in the CUDA device compilation and device-only
1109e8d8bef9SDimitry Andric   // functions in the host compilation. Just roughly filter them out based on
1110e8d8bef9SDimitry Andric   // the function attributes. If there are effectively host-only or device-only
1111e8d8bef9SDimitry Andric   // ones, their coverage mapping may still be generated.
1112e8d8bef9SDimitry Andric   if (CGM.getLangOpts().CUDA &&
1113e8d8bef9SDimitry Andric       ((CGM.getLangOpts().CUDAIsDevice && !D->hasAttr<CUDADeviceAttr>() &&
1114e8d8bef9SDimitry Andric         !D->hasAttr<CUDAGlobalAttr>()) ||
1115e8d8bef9SDimitry Andric        (!CGM.getLangOpts().CUDAIsDevice &&
1116e8d8bef9SDimitry Andric         (D->hasAttr<CUDAGlobalAttr>() ||
1117e8d8bef9SDimitry Andric          (!D->hasAttr<CUDAHostAttr>() && D->hasAttr<CUDADeviceAttr>())))))
1118e8d8bef9SDimitry Andric     return true;
1119e8d8bef9SDimitry Andric 
11200b57cec5SDimitry Andric   // Don't map the functions in system headers.
11210b57cec5SDimitry Andric   const auto &SM = CGM.getContext().getSourceManager();
11220b57cec5SDimitry Andric   auto Loc = D->getBody()->getBeginLoc();
1123*0fca6ea1SDimitry Andric   return !llvm::coverage::SystemHeadersCoverage && SM.isInSystemHeader(Loc);
11240b57cec5SDimitry Andric }
11250b57cec5SDimitry Andric 
11260b57cec5SDimitry Andric void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
11270b57cec5SDimitry Andric   if (skipRegionMappingForDecl(D))
11280b57cec5SDimitry Andric     return;
11290b57cec5SDimitry Andric 
11300b57cec5SDimitry Andric   std::string CoverageMapping;
11310b57cec5SDimitry Andric   llvm::raw_string_ostream OS(CoverageMapping);
1132*0fca6ea1SDimitry Andric   RegionMCDCState->BranchByStmt.clear();
11331db9f3b2SDimitry Andric   CoverageMappingGen MappingGen(
11341db9f3b2SDimitry Andric       *CGM.getCoverageMapping(), CGM.getContext().getSourceManager(),
1135*0fca6ea1SDimitry Andric       CGM.getLangOpts(), RegionCounterMap.get(), RegionMCDCState.get());
11360b57cec5SDimitry Andric   MappingGen.emitCounterMapping(D, OS);
11370b57cec5SDimitry Andric   OS.flush();
11380b57cec5SDimitry Andric 
11390b57cec5SDimitry Andric   if (CoverageMapping.empty())
11400b57cec5SDimitry Andric     return;
11410b57cec5SDimitry Andric 
11420b57cec5SDimitry Andric   CGM.getCoverageMapping()->addFunctionMappingRecord(
11430b57cec5SDimitry Andric       FuncNameVar, FuncName, FunctionHash, CoverageMapping);
11440b57cec5SDimitry Andric }
11450b57cec5SDimitry Andric 
11460b57cec5SDimitry Andric void
11470b57cec5SDimitry Andric CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef Name,
11480b57cec5SDimitry Andric                                     llvm::GlobalValue::LinkageTypes Linkage) {
11490b57cec5SDimitry Andric   if (skipRegionMappingForDecl(D))
11500b57cec5SDimitry Andric     return;
11510b57cec5SDimitry Andric 
11520b57cec5SDimitry Andric   std::string CoverageMapping;
11530b57cec5SDimitry Andric   llvm::raw_string_ostream OS(CoverageMapping);
11540b57cec5SDimitry Andric   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
11550b57cec5SDimitry Andric                                 CGM.getContext().getSourceManager(),
11560b57cec5SDimitry Andric                                 CGM.getLangOpts());
11570b57cec5SDimitry Andric   MappingGen.emitEmptyMapping(D, OS);
11580b57cec5SDimitry Andric   OS.flush();
11590b57cec5SDimitry Andric 
11600b57cec5SDimitry Andric   if (CoverageMapping.empty())
11610b57cec5SDimitry Andric     return;
11620b57cec5SDimitry Andric 
11630b57cec5SDimitry Andric   setFuncName(Name, Linkage);
11640b57cec5SDimitry Andric   CGM.getCoverageMapping()->addFunctionMappingRecord(
11650b57cec5SDimitry Andric       FuncNameVar, FuncName, FunctionHash, CoverageMapping, false);
11660b57cec5SDimitry Andric }
11670b57cec5SDimitry Andric 
11680b57cec5SDimitry Andric void CodeGenPGO::computeRegionCounts(const Decl *D) {
11690b57cec5SDimitry Andric   StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
11700b57cec5SDimitry Andric   ComputeRegionCounts Walker(*StmtCountMap, *this);
11710b57cec5SDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
11720b57cec5SDimitry Andric     Walker.VisitFunctionDecl(FD);
11730b57cec5SDimitry Andric   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
11740b57cec5SDimitry Andric     Walker.VisitObjCMethodDecl(MD);
11750b57cec5SDimitry Andric   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
11760b57cec5SDimitry Andric     Walker.VisitBlockDecl(BD);
11770b57cec5SDimitry Andric   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
11780b57cec5SDimitry Andric     Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
11790b57cec5SDimitry Andric }
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric void
11820b57cec5SDimitry Andric CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
11830b57cec5SDimitry Andric                                     llvm::Function *Fn) {
11840b57cec5SDimitry Andric   if (!haveRegionCounts())
11850b57cec5SDimitry Andric     return;
11860b57cec5SDimitry Andric 
11870b57cec5SDimitry Andric   uint64_t FunctionCount = getRegionCount(nullptr);
11880b57cec5SDimitry Andric   Fn->setEntryCount(FunctionCount);
11890b57cec5SDimitry Andric }
11900b57cec5SDimitry Andric 
1191*0fca6ea1SDimitry Andric void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S,
11920b57cec5SDimitry Andric                                            llvm::Value *StepV) {
11935f757f3fSDimitry Andric   if (!RegionCounterMap || !Builder.GetInsertBlock())
11940b57cec5SDimitry Andric     return;
11950b57cec5SDimitry Andric 
11960b57cec5SDimitry Andric   unsigned Counter = (*RegionCounterMap)[S];
11970b57cec5SDimitry Andric 
11985f757f3fSDimitry Andric   llvm::Value *Args[] = {FuncNameVar,
11990b57cec5SDimitry Andric                          Builder.getInt64(FunctionHash),
12000b57cec5SDimitry Andric                          Builder.getInt32(NumRegionCounters),
12010b57cec5SDimitry Andric                          Builder.getInt32(Counter), StepV};
1202*0fca6ea1SDimitry Andric 
1203*0fca6ea1SDimitry Andric   if (llvm::EnableSingleByteCoverage)
1204*0fca6ea1SDimitry Andric     Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_cover),
1205*0fca6ea1SDimitry Andric                        ArrayRef(Args, 4));
1206*0fca6ea1SDimitry Andric   else {
12070b57cec5SDimitry Andric     if (!StepV)
12080b57cec5SDimitry Andric       Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
1209bdd1243dSDimitry Andric                          ArrayRef(Args, 4));
12100b57cec5SDimitry Andric     else
12110b57cec5SDimitry Andric       Builder.CreateCall(
1212*0fca6ea1SDimitry Andric           CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment_step), Args);
1213*0fca6ea1SDimitry Andric   }
12140b57cec5SDimitry Andric }
12150b57cec5SDimitry Andric 
12161db9f3b2SDimitry Andric bool CodeGenPGO::canEmitMCDCCoverage(const CGBuilderTy &Builder) {
12171db9f3b2SDimitry Andric   return (CGM.getCodeGenOpts().hasProfileClangInstr() &&
12181db9f3b2SDimitry Andric           CGM.getCodeGenOpts().MCDCCoverage && Builder.GetInsertBlock());
12191db9f3b2SDimitry Andric }
12201db9f3b2SDimitry Andric 
12211db9f3b2SDimitry Andric void CodeGenPGO::emitMCDCParameters(CGBuilderTy &Builder) {
1222*0fca6ea1SDimitry Andric   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
12231db9f3b2SDimitry Andric     return;
12241db9f3b2SDimitry Andric 
12251db9f3b2SDimitry Andric   auto *I8PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
12261db9f3b2SDimitry Andric 
12271db9f3b2SDimitry Andric   // Emit intrinsic representing MCDC bitmap parameters at function entry.
12281db9f3b2SDimitry Andric   // This is used by the instrumentation pass, but it isn't actually lowered to
12291db9f3b2SDimitry Andric   // anything.
12301db9f3b2SDimitry Andric   llvm::Value *Args[3] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
12311db9f3b2SDimitry Andric                           Builder.getInt64(FunctionHash),
1232*0fca6ea1SDimitry Andric                           Builder.getInt32(RegionMCDCState->BitmapBits)};
12331db9f3b2SDimitry Andric   Builder.CreateCall(
12341db9f3b2SDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_parameters), Args);
12351db9f3b2SDimitry Andric }
12361db9f3b2SDimitry Andric 
12371db9f3b2SDimitry Andric void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
12381db9f3b2SDimitry Andric                                                 const Expr *S,
1239*0fca6ea1SDimitry Andric                                                 Address MCDCCondBitmapAddr,
1240*0fca6ea1SDimitry Andric                                                 CodeGenFunction &CGF) {
1241*0fca6ea1SDimitry Andric   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
12421db9f3b2SDimitry Andric     return;
12431db9f3b2SDimitry Andric 
12441db9f3b2SDimitry Andric   S = S->IgnoreParens();
12451db9f3b2SDimitry Andric 
1246*0fca6ea1SDimitry Andric   auto DecisionStateIter = RegionMCDCState->DecisionByStmt.find(S);
1247*0fca6ea1SDimitry Andric   if (DecisionStateIter == RegionMCDCState->DecisionByStmt.end())
12481db9f3b2SDimitry Andric     return;
12491db9f3b2SDimitry Andric 
1250*0fca6ea1SDimitry Andric   // Don't create tvbitmap_update if the record is allocated but excluded.
1251*0fca6ea1SDimitry Andric   // Or `bitmap |= (1 << 0)` would be wrongly executed to the next bitmap.
1252*0fca6ea1SDimitry Andric   if (DecisionStateIter->second.Indices.size() == 0)
1253*0fca6ea1SDimitry Andric     return;
1254*0fca6ea1SDimitry Andric 
1255*0fca6ea1SDimitry Andric   // Extract the offset of the global bitmap associated with this expression.
1256*0fca6ea1SDimitry Andric   unsigned MCDCTestVectorBitmapOffset = DecisionStateIter->second.BitmapIdx;
12571db9f3b2SDimitry Andric   auto *I8PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
12581db9f3b2SDimitry Andric 
12591db9f3b2SDimitry Andric   // Emit intrinsic responsible for updating the global bitmap corresponding to
12601db9f3b2SDimitry Andric   // a boolean expression. The index being set is based on the value loaded
12611db9f3b2SDimitry Andric   // from a pointer to a dedicated temporary value on the stack that is itself
12621db9f3b2SDimitry Andric   // updated via emitMCDCCondBitmapReset() and emitMCDCCondBitmapUpdate(). The
12631db9f3b2SDimitry Andric   // index represents an executed test vector.
1264*0fca6ea1SDimitry Andric   llvm::Value *Args[4] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
12651db9f3b2SDimitry Andric                           Builder.getInt64(FunctionHash),
1266*0fca6ea1SDimitry Andric                           Builder.getInt32(MCDCTestVectorBitmapOffset),
1267*0fca6ea1SDimitry Andric                           MCDCCondBitmapAddr.emitRawPointer(CGF)};
12681db9f3b2SDimitry Andric   Builder.CreateCall(
12691db9f3b2SDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_tvbitmap_update), Args);
12701db9f3b2SDimitry Andric }
12711db9f3b2SDimitry Andric 
12721db9f3b2SDimitry Andric void CodeGenPGO::emitMCDCCondBitmapReset(CGBuilderTy &Builder, const Expr *S,
12731db9f3b2SDimitry Andric                                          Address MCDCCondBitmapAddr) {
1274*0fca6ea1SDimitry Andric   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
12751db9f3b2SDimitry Andric     return;
12761db9f3b2SDimitry Andric 
12771db9f3b2SDimitry Andric   S = S->IgnoreParens();
12781db9f3b2SDimitry Andric 
1279*0fca6ea1SDimitry Andric   if (!RegionMCDCState->DecisionByStmt.contains(S))
12801db9f3b2SDimitry Andric     return;
12811db9f3b2SDimitry Andric 
12821db9f3b2SDimitry Andric   // Emit intrinsic that resets a dedicated temporary value on the stack to 0.
12831db9f3b2SDimitry Andric   Builder.CreateStore(Builder.getInt32(0), MCDCCondBitmapAddr);
12841db9f3b2SDimitry Andric }
12851db9f3b2SDimitry Andric 
12861db9f3b2SDimitry Andric void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S,
12871db9f3b2SDimitry Andric                                           Address MCDCCondBitmapAddr,
1288*0fca6ea1SDimitry Andric                                           llvm::Value *Val,
1289*0fca6ea1SDimitry Andric                                           CodeGenFunction &CGF) {
1290*0fca6ea1SDimitry Andric   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
12911db9f3b2SDimitry Andric     return;
12921db9f3b2SDimitry Andric 
12931db9f3b2SDimitry Andric   // Even though, for simplicity, parentheses and unary logical-NOT operators
12941db9f3b2SDimitry Andric   // are considered part of their underlying condition for both MC/DC and
12951db9f3b2SDimitry Andric   // branch coverage, the condition IDs themselves are assigned and tracked
12961db9f3b2SDimitry Andric   // using the underlying condition itself.  This is done solely for
12971db9f3b2SDimitry Andric   // consistency since parentheses and logical-NOTs are ignored when checking
12981db9f3b2SDimitry Andric   // whether the condition is actually an instrumentable condition. This can
12991db9f3b2SDimitry Andric   // also make debugging a bit easier.
13001db9f3b2SDimitry Andric   S = CodeGenFunction::stripCond(S);
13011db9f3b2SDimitry Andric 
1302*0fca6ea1SDimitry Andric   auto BranchStateIter = RegionMCDCState->BranchByStmt.find(S);
1303*0fca6ea1SDimitry Andric   if (BranchStateIter == RegionMCDCState->BranchByStmt.end())
13041db9f3b2SDimitry Andric     return;
13051db9f3b2SDimitry Andric 
13061db9f3b2SDimitry Andric   // Extract the ID of the condition we are setting in the bitmap.
1307*0fca6ea1SDimitry Andric   const auto &Branch = BranchStateIter->second;
1308*0fca6ea1SDimitry Andric   assert(Branch.ID >= 0 && "Condition has no ID!");
1309*0fca6ea1SDimitry Andric   assert(Branch.DecisionStmt);
13101db9f3b2SDimitry Andric 
1311*0fca6ea1SDimitry Andric   // Cancel the emission if the Decision is erased after the allocation.
1312*0fca6ea1SDimitry Andric   const auto DecisionIter =
1313*0fca6ea1SDimitry Andric       RegionMCDCState->DecisionByStmt.find(Branch.DecisionStmt);
1314*0fca6ea1SDimitry Andric   if (DecisionIter == RegionMCDCState->DecisionByStmt.end())
1315*0fca6ea1SDimitry Andric     return;
13161db9f3b2SDimitry Andric 
1317*0fca6ea1SDimitry Andric   const auto &TVIdxs = DecisionIter->second.Indices[Branch.ID];
1318*0fca6ea1SDimitry Andric 
1319*0fca6ea1SDimitry Andric   auto *CurTV = Builder.CreateLoad(MCDCCondBitmapAddr,
1320*0fca6ea1SDimitry Andric                                    "mcdc." + Twine(Branch.ID + 1) + ".cur");
1321*0fca6ea1SDimitry Andric   auto *NewTV = Builder.CreateAdd(CurTV, Builder.getInt32(TVIdxs[true]));
1322*0fca6ea1SDimitry Andric   NewTV = Builder.CreateSelect(
1323*0fca6ea1SDimitry Andric       Val, NewTV, Builder.CreateAdd(CurTV, Builder.getInt32(TVIdxs[false])));
1324*0fca6ea1SDimitry Andric   Builder.CreateStore(NewTV, MCDCCondBitmapAddr);
13251db9f3b2SDimitry Andric }
13261db9f3b2SDimitry Andric 
1327fe6060f1SDimitry Andric void CodeGenPGO::setValueProfilingFlag(llvm::Module &M) {
1328fe6060f1SDimitry Andric   if (CGM.getCodeGenOpts().hasProfileClangInstr())
1329fe6060f1SDimitry Andric     M.addModuleFlag(llvm::Module::Warning, "EnableValueProfiling",
1330fe6060f1SDimitry Andric                     uint32_t(EnableValueProfiling));
1331fe6060f1SDimitry Andric }
1332fe6060f1SDimitry Andric 
1333*0fca6ea1SDimitry Andric void CodeGenPGO::setProfileVersion(llvm::Module &M) {
1334*0fca6ea1SDimitry Andric   if (CGM.getCodeGenOpts().hasProfileClangInstr() &&
1335*0fca6ea1SDimitry Andric       llvm::EnableSingleByteCoverage) {
1336*0fca6ea1SDimitry Andric     const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
1337*0fca6ea1SDimitry Andric     llvm::Type *IntTy64 = llvm::Type::getInt64Ty(M.getContext());
1338*0fca6ea1SDimitry Andric     uint64_t ProfileVersion =
1339*0fca6ea1SDimitry Andric         (INSTR_PROF_RAW_VERSION | VARIANT_MASK_BYTE_COVERAGE);
1340*0fca6ea1SDimitry Andric 
1341*0fca6ea1SDimitry Andric     auto IRLevelVersionVariable = new llvm::GlobalVariable(
1342*0fca6ea1SDimitry Andric         M, IntTy64, true, llvm::GlobalValue::WeakAnyLinkage,
1343*0fca6ea1SDimitry Andric         llvm::Constant::getIntegerValue(IntTy64,
1344*0fca6ea1SDimitry Andric                                         llvm::APInt(64, ProfileVersion)),
1345*0fca6ea1SDimitry Andric         VarName);
1346*0fca6ea1SDimitry Andric 
1347*0fca6ea1SDimitry Andric     IRLevelVersionVariable->setVisibility(llvm::GlobalValue::HiddenVisibility);
1348*0fca6ea1SDimitry Andric     llvm::Triple TT(M.getTargetTriple());
1349*0fca6ea1SDimitry Andric     if (TT.supportsCOMDAT()) {
1350*0fca6ea1SDimitry Andric       IRLevelVersionVariable->setLinkage(llvm::GlobalValue::ExternalLinkage);
1351*0fca6ea1SDimitry Andric       IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName));
1352*0fca6ea1SDimitry Andric     }
1353*0fca6ea1SDimitry Andric     IRLevelVersionVariable->setDSOLocal(true);
1354*0fca6ea1SDimitry Andric   }
1355*0fca6ea1SDimitry Andric }
1356*0fca6ea1SDimitry Andric 
13570b57cec5SDimitry Andric // This method either inserts a call to the profile run-time during
13580b57cec5SDimitry Andric // instrumentation or puts profile data into metadata for PGO use.
13590b57cec5SDimitry Andric void CodeGenPGO::valueProfile(CGBuilderTy &Builder, uint32_t ValueKind,
13600b57cec5SDimitry Andric     llvm::Instruction *ValueSite, llvm::Value *ValuePtr) {
13610b57cec5SDimitry Andric 
13620b57cec5SDimitry Andric   if (!EnableValueProfiling)
13630b57cec5SDimitry Andric     return;
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric   if (!ValuePtr || !ValueSite || !Builder.GetInsertBlock())
13660b57cec5SDimitry Andric     return;
13670b57cec5SDimitry Andric 
13680b57cec5SDimitry Andric   if (isa<llvm::Constant>(ValuePtr))
13690b57cec5SDimitry Andric     return;
13700b57cec5SDimitry Andric 
13710b57cec5SDimitry Andric   bool InstrumentValueSites = CGM.getCodeGenOpts().hasProfileClangInstr();
13720b57cec5SDimitry Andric   if (InstrumentValueSites && RegionCounterMap) {
13730b57cec5SDimitry Andric     auto BuilderInsertPoint = Builder.saveIP();
13740b57cec5SDimitry Andric     Builder.SetInsertPoint(ValueSite);
13750b57cec5SDimitry Andric     llvm::Value *Args[5] = {
13765f757f3fSDimitry Andric         FuncNameVar,
13770b57cec5SDimitry Andric         Builder.getInt64(FunctionHash),
13780b57cec5SDimitry Andric         Builder.CreatePtrToInt(ValuePtr, Builder.getInt64Ty()),
13790b57cec5SDimitry Andric         Builder.getInt32(ValueKind),
13800b57cec5SDimitry Andric         Builder.getInt32(NumValueSites[ValueKind]++)
13810b57cec5SDimitry Andric     };
13820b57cec5SDimitry Andric     Builder.CreateCall(
13830b57cec5SDimitry Andric         CGM.getIntrinsic(llvm::Intrinsic::instrprof_value_profile), Args);
13840b57cec5SDimitry Andric     Builder.restoreIP(BuilderInsertPoint);
13850b57cec5SDimitry Andric     return;
13860b57cec5SDimitry Andric   }
13870b57cec5SDimitry Andric 
13880b57cec5SDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
13890b57cec5SDimitry Andric   if (PGOReader && haveRegionCounts()) {
13900b57cec5SDimitry Andric     // We record the top most called three functions at each call site.
13910b57cec5SDimitry Andric     // Profile metadata contains "VP" string identifying this metadata
13920b57cec5SDimitry Andric     // as value profiling data, then a uint32_t value for the value profiling
13930b57cec5SDimitry Andric     // kind, a uint64_t value for the total number of times the call is
13940b57cec5SDimitry Andric     // executed, followed by the function hash and execution count (uint64_t)
13950b57cec5SDimitry Andric     // pairs for each function.
13960b57cec5SDimitry Andric     if (NumValueSites[ValueKind] >= ProfRecord->getNumValueSites(ValueKind))
13970b57cec5SDimitry Andric       return;
13980b57cec5SDimitry Andric 
13990b57cec5SDimitry Andric     llvm::annotateValueSite(CGM.getModule(), *ValueSite, *ProfRecord,
14000b57cec5SDimitry Andric                             (llvm::InstrProfValueKind)ValueKind,
14010b57cec5SDimitry Andric                             NumValueSites[ValueKind]);
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric     NumValueSites[ValueKind]++;
14040b57cec5SDimitry Andric   }
14050b57cec5SDimitry Andric }
14060b57cec5SDimitry Andric 
14070b57cec5SDimitry Andric void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
14080b57cec5SDimitry Andric                                   bool IsInMainFile) {
14090b57cec5SDimitry Andric   CGM.getPGOStats().addVisited(IsInMainFile);
14100b57cec5SDimitry Andric   RegionCounts.clear();
14110b57cec5SDimitry Andric   llvm::Expected<llvm::InstrProfRecord> RecordExpected =
14120b57cec5SDimitry Andric       PGOReader->getInstrProfRecord(FuncName, FunctionHash);
14130b57cec5SDimitry Andric   if (auto E = RecordExpected.takeError()) {
141406c3fb27SDimitry Andric     auto IPE = std::get<0>(llvm::InstrProfError::take(std::move(E)));
14150b57cec5SDimitry Andric     if (IPE == llvm::instrprof_error::unknown_function)
14160b57cec5SDimitry Andric       CGM.getPGOStats().addMissing(IsInMainFile);
14170b57cec5SDimitry Andric     else if (IPE == llvm::instrprof_error::hash_mismatch)
14180b57cec5SDimitry Andric       CGM.getPGOStats().addMismatched(IsInMainFile);
14190b57cec5SDimitry Andric     else if (IPE == llvm::instrprof_error::malformed)
14200b57cec5SDimitry Andric       // TODO: Consider a more specific warning for this case.
14210b57cec5SDimitry Andric       CGM.getPGOStats().addMismatched(IsInMainFile);
14220b57cec5SDimitry Andric     return;
14230b57cec5SDimitry Andric   }
14240b57cec5SDimitry Andric   ProfRecord =
1425a7dea167SDimitry Andric       std::make_unique<llvm::InstrProfRecord>(std::move(RecordExpected.get()));
14260b57cec5SDimitry Andric   RegionCounts = ProfRecord->Counts;
14270b57cec5SDimitry Andric }
14280b57cec5SDimitry Andric 
14290b57cec5SDimitry Andric /// Calculate what to divide by to scale weights.
14300b57cec5SDimitry Andric ///
14310b57cec5SDimitry Andric /// Given the maximum weight, calculate a divisor that will scale all the
14320b57cec5SDimitry Andric /// weights to strictly less than UINT32_MAX.
14330b57cec5SDimitry Andric static uint64_t calculateWeightScale(uint64_t MaxWeight) {
14340b57cec5SDimitry Andric   return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
14350b57cec5SDimitry Andric }
14360b57cec5SDimitry Andric 
14370b57cec5SDimitry Andric /// Scale an individual branch weight (and add 1).
14380b57cec5SDimitry Andric ///
14390b57cec5SDimitry Andric /// Scale a 64-bit weight down to 32-bits using \c Scale.
14400b57cec5SDimitry Andric ///
14410b57cec5SDimitry Andric /// According to Laplace's Rule of Succession, it is better to compute the
14420b57cec5SDimitry Andric /// weight based on the count plus 1, so universally add 1 to the value.
14430b57cec5SDimitry Andric ///
14440b57cec5SDimitry Andric /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
14450b57cec5SDimitry Andric /// greater than \c Weight.
14460b57cec5SDimitry Andric static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
14470b57cec5SDimitry Andric   assert(Scale && "scale by 0?");
14480b57cec5SDimitry Andric   uint64_t Scaled = Weight / Scale + 1;
14490b57cec5SDimitry Andric   assert(Scaled <= UINT32_MAX && "overflow 32-bits");
14500b57cec5SDimitry Andric   return Scaled;
14510b57cec5SDimitry Andric }
14520b57cec5SDimitry Andric 
14530b57cec5SDimitry Andric llvm::MDNode *CodeGenFunction::createProfileWeights(uint64_t TrueCount,
1454e8d8bef9SDimitry Andric                                                     uint64_t FalseCount) const {
14550b57cec5SDimitry Andric   // Check for empty weights.
14560b57cec5SDimitry Andric   if (!TrueCount && !FalseCount)
14570b57cec5SDimitry Andric     return nullptr;
14580b57cec5SDimitry Andric 
14590b57cec5SDimitry Andric   // Calculate how to scale down to 32-bits.
14600b57cec5SDimitry Andric   uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
14610b57cec5SDimitry Andric 
14620b57cec5SDimitry Andric   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
14630b57cec5SDimitry Andric   return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
14640b57cec5SDimitry Andric                                       scaleBranchWeight(FalseCount, Scale));
14650b57cec5SDimitry Andric }
14660b57cec5SDimitry Andric 
14670b57cec5SDimitry Andric llvm::MDNode *
1468e8d8bef9SDimitry Andric CodeGenFunction::createProfileWeights(ArrayRef<uint64_t> Weights) const {
14690b57cec5SDimitry Andric   // We need at least two elements to create meaningful weights.
14700b57cec5SDimitry Andric   if (Weights.size() < 2)
14710b57cec5SDimitry Andric     return nullptr;
14720b57cec5SDimitry Andric 
14730b57cec5SDimitry Andric   // Check for empty weights.
14740b57cec5SDimitry Andric   uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
14750b57cec5SDimitry Andric   if (MaxWeight == 0)
14760b57cec5SDimitry Andric     return nullptr;
14770b57cec5SDimitry Andric 
14780b57cec5SDimitry Andric   // Calculate how to scale down to 32-bits.
14790b57cec5SDimitry Andric   uint64_t Scale = calculateWeightScale(MaxWeight);
14800b57cec5SDimitry Andric 
14810b57cec5SDimitry Andric   SmallVector<uint32_t, 16> ScaledWeights;
14820b57cec5SDimitry Andric   ScaledWeights.reserve(Weights.size());
14830b57cec5SDimitry Andric   for (uint64_t W : Weights)
14840b57cec5SDimitry Andric     ScaledWeights.push_back(scaleBranchWeight(W, Scale));
14850b57cec5SDimitry Andric 
14860b57cec5SDimitry Andric   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
14870b57cec5SDimitry Andric   return MDHelper.createBranchWeights(ScaledWeights);
14880b57cec5SDimitry Andric }
14890b57cec5SDimitry Andric 
1490e8d8bef9SDimitry Andric llvm::MDNode *
1491e8d8bef9SDimitry Andric CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond,
1492e8d8bef9SDimitry Andric                                              uint64_t LoopCount) const {
14930b57cec5SDimitry Andric   if (!PGO.haveRegionCounts())
14940b57cec5SDimitry Andric     return nullptr;
1495bdd1243dSDimitry Andric   std::optional<uint64_t> CondCount = PGO.getStmtCount(Cond);
14965ffd83dbSDimitry Andric   if (!CondCount || *CondCount == 0)
14970b57cec5SDimitry Andric     return nullptr;
14980b57cec5SDimitry Andric   return createProfileWeights(LoopCount,
14990b57cec5SDimitry Andric                               std::max(*CondCount, LoopCount) - LoopCount);
15000b57cec5SDimitry Andric }
1501