xref: /src/contrib/llvm-project/clang/lib/CodeGen/CodeGenPGO.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
19f4dbff6SDimitry Andric //===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- C++ -*-===//
29f4dbff6SDimitry Andric //
322989816SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
422989816SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
522989816SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69f4dbff6SDimitry Andric //
79f4dbff6SDimitry Andric //===----------------------------------------------------------------------===//
89f4dbff6SDimitry Andric //
99f4dbff6SDimitry Andric // Instrumentation-based profile-guided optimization
109f4dbff6SDimitry Andric //
119f4dbff6SDimitry Andric //===----------------------------------------------------------------------===//
129f4dbff6SDimitry Andric 
139f4dbff6SDimitry Andric #include "CodeGenPGO.h"
149f4dbff6SDimitry Andric #include "CodeGenFunction.h"
1506d4ba38SDimitry Andric #include "CoverageMappingGen.h"
169f4dbff6SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
179f4dbff6SDimitry Andric #include "clang/AST/StmtVisitor.h"
1806d4ba38SDimitry Andric #include "llvm/IR/Intrinsics.h"
199f4dbff6SDimitry Andric #include "llvm/IR/MDBuilder.h"
20706b4fc4SDimitry Andric #include "llvm/Support/CommandLine.h"
219f4dbff6SDimitry Andric #include "llvm/Support/Endian.h"
229f4dbff6SDimitry Andric #include "llvm/Support/FileSystem.h"
239f4dbff6SDimitry Andric #include "llvm/Support/MD5.h"
24e3b55780SDimitry Andric #include <optional>
259f4dbff6SDimitry Andric 
26ac9a064cSDimitry Andric namespace llvm {
27ac9a064cSDimitry Andric extern cl::opt<bool> EnableSingleByteCoverage;
28ac9a064cSDimitry Andric } // namespace llvm
29ac9a064cSDimitry Andric 
30461a67faSDimitry Andric static llvm::cl::opt<bool>
31145449b1SDimitry Andric     EnableValueProfiling("enable-value-profiling",
32461a67faSDimitry Andric                          llvm::cl::desc("Enable value profiling"),
33461a67faSDimitry Andric                          llvm::cl::Hidden, llvm::cl::init(false));
342b6b257fSDimitry Andric 
359f4dbff6SDimitry Andric using namespace clang;
369f4dbff6SDimitry Andric using namespace CodeGen;
379f4dbff6SDimitry Andric 
setFuncName(StringRef Name,llvm::GlobalValue::LinkageTypes Linkage)3806d4ba38SDimitry Andric void CodeGenPGO::setFuncName(StringRef Name,
3906d4ba38SDimitry Andric                              llvm::GlobalValue::LinkageTypes Linkage) {
4045b53394SDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
4145b53394SDimitry Andric   FuncName = llvm::getPGOFuncName(
4245b53394SDimitry Andric       Name, Linkage, CGM.getCodeGenOpts().MainFileName,
4345b53394SDimitry Andric       PGOReader ? PGOReader->getVersion() : llvm::IndexedInstrProf::Version);
449f4dbff6SDimitry Andric 
4506d4ba38SDimitry Andric   // If we're generating a profile, create a variable for the name.
462b6b257fSDimitry Andric   if (CGM.getCodeGenOpts().hasProfileClangInstr())
4745b53394SDimitry Andric     FuncNameVar = llvm::createPGOFuncNameVar(CGM.getModule(), Linkage, FuncName);
489f4dbff6SDimitry Andric }
499f4dbff6SDimitry Andric 
setFuncName(llvm::Function * Fn)5006d4ba38SDimitry Andric void CodeGenPGO::setFuncName(llvm::Function *Fn) {
5106d4ba38SDimitry Andric   setFuncName(Fn->getName(), Fn->getLinkage());
522b6b257fSDimitry Andric   // Create PGOFuncName meta data.
532b6b257fSDimitry Andric   llvm::createPGOFuncNameMetadata(*Fn, FuncName);
549f4dbff6SDimitry Andric }
559f4dbff6SDimitry Andric 
56461a67faSDimitry Andric /// The version of the PGO hash algorithm.
57461a67faSDimitry Andric enum PGOHashVersion : unsigned {
58461a67faSDimitry Andric   PGO_HASH_V1,
59461a67faSDimitry Andric   PGO_HASH_V2,
60cfca06d7SDimitry Andric   PGO_HASH_V3,
61461a67faSDimitry Andric 
62461a67faSDimitry Andric   // Keep this set to the latest hash version.
63cfca06d7SDimitry Andric   PGO_HASH_LATEST = PGO_HASH_V3
64461a67faSDimitry Andric };
65461a67faSDimitry Andric 
669f4dbff6SDimitry Andric namespace {
6748675466SDimitry Andric /// Stable hasher for PGO region counters.
689f4dbff6SDimitry Andric ///
699f4dbff6SDimitry Andric /// PGOHash produces a stable hash of a given function's control flow.
709f4dbff6SDimitry Andric ///
719f4dbff6SDimitry Andric /// Changing the output of this hash will invalidate all previously generated
729f4dbff6SDimitry Andric /// profiles -- i.e., don't do it.
739f4dbff6SDimitry Andric ///
749f4dbff6SDimitry Andric /// \note  When this hash does eventually change (years?), we still need to
759f4dbff6SDimitry Andric /// support old hashes.  We'll need to pull in the version number from the
769f4dbff6SDimitry Andric /// profile data format and use the matching hash function.
779f4dbff6SDimitry Andric class PGOHash {
789f4dbff6SDimitry Andric   uint64_t Working;
799f4dbff6SDimitry Andric   unsigned Count;
80461a67faSDimitry Andric   PGOHashVersion HashVersion;
819f4dbff6SDimitry Andric   llvm::MD5 MD5;
829f4dbff6SDimitry Andric 
839f4dbff6SDimitry Andric   static const int NumBitsPerType = 6;
849f4dbff6SDimitry Andric   static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
859f4dbff6SDimitry Andric   static const unsigned TooBig = 1u << NumBitsPerType;
869f4dbff6SDimitry Andric 
879f4dbff6SDimitry Andric public:
8848675466SDimitry Andric   /// Hash values for AST nodes.
899f4dbff6SDimitry Andric   ///
909f4dbff6SDimitry Andric   /// Distinct values for AST nodes that have region counters attached.
919f4dbff6SDimitry Andric   ///
929f4dbff6SDimitry Andric   /// These values must be stable.  All new members must be added at the end,
939f4dbff6SDimitry Andric   /// and no members should be removed.  Changing the enumeration value for an
949f4dbff6SDimitry Andric   /// AST node will affect the hash of every function that contains that node.
959f4dbff6SDimitry Andric   enum HashType : unsigned char {
969f4dbff6SDimitry Andric     None = 0,
979f4dbff6SDimitry Andric     LabelStmt = 1,
989f4dbff6SDimitry Andric     WhileStmt,
999f4dbff6SDimitry Andric     DoStmt,
1009f4dbff6SDimitry Andric     ForStmt,
1019f4dbff6SDimitry Andric     CXXForRangeStmt,
1029f4dbff6SDimitry Andric     ObjCForCollectionStmt,
1039f4dbff6SDimitry Andric     SwitchStmt,
1049f4dbff6SDimitry Andric     CaseStmt,
1059f4dbff6SDimitry Andric     DefaultStmt,
1069f4dbff6SDimitry Andric     IfStmt,
1079f4dbff6SDimitry Andric     CXXTryStmt,
1089f4dbff6SDimitry Andric     CXXCatchStmt,
1099f4dbff6SDimitry Andric     ConditionalOperator,
1109f4dbff6SDimitry Andric     BinaryOperatorLAnd,
1119f4dbff6SDimitry Andric     BinaryOperatorLOr,
1129f4dbff6SDimitry Andric     BinaryConditionalOperator,
113461a67faSDimitry Andric     // The preceding values are available with PGO_HASH_V1.
114461a67faSDimitry Andric 
115461a67faSDimitry Andric     EndOfScope,
116461a67faSDimitry Andric     IfThenBranch,
117461a67faSDimitry Andric     IfElseBranch,
118461a67faSDimitry Andric     GotoStmt,
119461a67faSDimitry Andric     IndirectGotoStmt,
120461a67faSDimitry Andric     BreakStmt,
121461a67faSDimitry Andric     ContinueStmt,
122461a67faSDimitry Andric     ReturnStmt,
123461a67faSDimitry Andric     ThrowExpr,
124461a67faSDimitry Andric     UnaryOperatorLNot,
125461a67faSDimitry Andric     BinaryOperatorLT,
126461a67faSDimitry Andric     BinaryOperatorGT,
127461a67faSDimitry Andric     BinaryOperatorLE,
128461a67faSDimitry Andric     BinaryOperatorGE,
129461a67faSDimitry Andric     BinaryOperatorEQ,
130461a67faSDimitry Andric     BinaryOperatorNE,
131cfca06d7SDimitry Andric     // The preceding values are available since PGO_HASH_V2.
1329f4dbff6SDimitry Andric 
1339f4dbff6SDimitry Andric     // Keep this last.  It's for the static assert that follows.
1349f4dbff6SDimitry Andric     LastHashType
1359f4dbff6SDimitry Andric   };
1369f4dbff6SDimitry Andric   static_assert(LastHashType <= TooBig, "Too many types in HashType");
1379f4dbff6SDimitry Andric 
PGOHash(PGOHashVersion HashVersion)138461a67faSDimitry Andric   PGOHash(PGOHashVersion HashVersion)
1396f8fc217SDimitry Andric       : Working(0), Count(0), HashVersion(HashVersion) {}
1409f4dbff6SDimitry Andric   void combine(HashType Type);
1419f4dbff6SDimitry Andric   uint64_t finalize();
getHashVersion() const142461a67faSDimitry Andric   PGOHashVersion getHashVersion() const { return HashVersion; }
1439f4dbff6SDimitry Andric };
1449f4dbff6SDimitry Andric const int PGOHash::NumBitsPerType;
1459f4dbff6SDimitry Andric const unsigned PGOHash::NumTypesPerWord;
1469f4dbff6SDimitry Andric const unsigned PGOHash::TooBig;
1479f4dbff6SDimitry Andric 
148461a67faSDimitry Andric /// Get the PGO hash version used in the given indexed profile.
getPGOHashVersion(llvm::IndexedInstrProfReader * PGOReader,CodeGenModule & CGM)149461a67faSDimitry Andric static PGOHashVersion getPGOHashVersion(llvm::IndexedInstrProfReader *PGOReader,
150461a67faSDimitry Andric                                         CodeGenModule &CGM) {
151461a67faSDimitry Andric   if (PGOReader->getVersion() <= 4)
152461a67faSDimitry Andric     return PGO_HASH_V1;
153cfca06d7SDimitry Andric   if (PGOReader->getVersion() <= 5)
154461a67faSDimitry Andric     return PGO_HASH_V2;
155cfca06d7SDimitry Andric   return PGO_HASH_V3;
156461a67faSDimitry Andric }
157461a67faSDimitry Andric 
1589f4dbff6SDimitry Andric /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
1599f4dbff6SDimitry Andric struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
160461a67faSDimitry Andric   using Base = RecursiveASTVisitor<MapRegionCounters>;
161461a67faSDimitry Andric 
1629f4dbff6SDimitry Andric   /// The next counter value to assign.
1639f4dbff6SDimitry Andric   unsigned NextCounter;
1649f4dbff6SDimitry Andric   /// The function hash.
1659f4dbff6SDimitry Andric   PGOHash Hash;
1669f4dbff6SDimitry Andric   /// The map of statements to counters.
1679f4dbff6SDimitry Andric   llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
168ac9a064cSDimitry Andric   /// The state of MC/DC Coverage in this function.
169ac9a064cSDimitry Andric   MCDC::State &MCDCState;
170aca2e42cSDimitry Andric   /// Maximum number of supported MC/DC conditions in a boolean expression.
171aca2e42cSDimitry Andric   unsigned MCDCMaxCond;
172b60736ecSDimitry Andric   /// The profile version.
173b60736ecSDimitry Andric   uint64_t ProfileVersion;
174aca2e42cSDimitry Andric   /// Diagnostics Engine used to report warnings.
175aca2e42cSDimitry Andric   DiagnosticsEngine &Diag;
1769f4dbff6SDimitry Andric 
MapRegionCounters__anone8f20fae0111::MapRegionCounters177b60736ecSDimitry Andric   MapRegionCounters(PGOHashVersion HashVersion, uint64_t ProfileVersion,
178aca2e42cSDimitry Andric                     llvm::DenseMap<const Stmt *, unsigned> &CounterMap,
179ac9a064cSDimitry Andric                     MCDC::State &MCDCState, unsigned MCDCMaxCond,
180ac9a064cSDimitry Andric                     DiagnosticsEngine &Diag)
181b60736ecSDimitry Andric       : NextCounter(0), Hash(HashVersion), CounterMap(CounterMap),
182ac9a064cSDimitry Andric         MCDCState(MCDCState), MCDCMaxCond(MCDCMaxCond),
183ac9a064cSDimitry Andric         ProfileVersion(ProfileVersion), Diag(Diag) {}
1849f4dbff6SDimitry Andric 
1859f4dbff6SDimitry Andric   // Blocks and lambdas are handled as separate functions, so we need not
1869f4dbff6SDimitry Andric   // traverse them in the parent context.
TraverseBlockExpr__anone8f20fae0111::MapRegionCounters1879f4dbff6SDimitry Andric   bool TraverseBlockExpr(BlockExpr *BE) { return true; }
TraverseLambdaExpr__anone8f20fae0111::MapRegionCounters188676fbe81SDimitry Andric   bool TraverseLambdaExpr(LambdaExpr *LE) {
189676fbe81SDimitry Andric     // Traverse the captures, but not the body.
190706b4fc4SDimitry Andric     for (auto C : zip(LE->captures(), LE->capture_inits()))
191676fbe81SDimitry Andric       TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
192676fbe81SDimitry Andric     return true;
193676fbe81SDimitry Andric   }
TraverseCapturedStmt__anone8f20fae0111::MapRegionCounters1949f4dbff6SDimitry Andric   bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
1959f4dbff6SDimitry Andric 
VisitDecl__anone8f20fae0111::MapRegionCounters1969f4dbff6SDimitry Andric   bool VisitDecl(const Decl *D) {
1979f4dbff6SDimitry Andric     switch (D->getKind()) {
1989f4dbff6SDimitry Andric     default:
1999f4dbff6SDimitry Andric       break;
2009f4dbff6SDimitry Andric     case Decl::Function:
2019f4dbff6SDimitry Andric     case Decl::CXXMethod:
2029f4dbff6SDimitry Andric     case Decl::CXXConstructor:
2039f4dbff6SDimitry Andric     case Decl::CXXDestructor:
2049f4dbff6SDimitry Andric     case Decl::CXXConversion:
2059f4dbff6SDimitry Andric     case Decl::ObjCMethod:
2069f4dbff6SDimitry Andric     case Decl::Block:
2079f4dbff6SDimitry Andric     case Decl::Captured:
2089f4dbff6SDimitry Andric       CounterMap[D->getBody()] = NextCounter++;
2099f4dbff6SDimitry Andric       break;
2109f4dbff6SDimitry Andric     }
2119f4dbff6SDimitry Andric     return true;
2129f4dbff6SDimitry Andric   }
2139f4dbff6SDimitry Andric 
214461a67faSDimitry Andric   /// If \p S gets a fresh counter, update the counter mappings. Return the
215461a67faSDimitry Andric   /// V1 hash of \p S.
updateCounterMappings__anone8f20fae0111::MapRegionCounters216461a67faSDimitry Andric   PGOHash::HashType updateCounterMappings(Stmt *S) {
217461a67faSDimitry Andric     auto Type = getHashType(PGO_HASH_V1, S);
218461a67faSDimitry Andric     if (Type != PGOHash::None)
2199f4dbff6SDimitry Andric       CounterMap[S] = NextCounter++;
220461a67faSDimitry Andric     return Type;
221461a67faSDimitry Andric   }
222461a67faSDimitry Andric 
223aca2e42cSDimitry Andric   /// The following stacks are used with dataTraverseStmtPre() and
224aca2e42cSDimitry Andric   /// dataTraverseStmtPost() to track the depth of nested logical operators in a
225aca2e42cSDimitry Andric   /// boolean expression in a function.  The ultimate purpose is to keep track
226aca2e42cSDimitry Andric   /// of the number of leaf-level conditions in the boolean expression so that a
227aca2e42cSDimitry Andric   /// profile bitmap can be allocated based on that number.
228aca2e42cSDimitry Andric   ///
229aca2e42cSDimitry Andric   /// The stacks are also used to find error cases and notify the user.  A
230aca2e42cSDimitry Andric   /// standard logical operator nest for a boolean expression could be in a form
231aca2e42cSDimitry Andric   /// similar to this: "x = a && b && c && (d || f)"
232aca2e42cSDimitry Andric   unsigned NumCond = 0;
233aca2e42cSDimitry Andric   bool SplitNestedLogicalOp = false;
234aca2e42cSDimitry Andric   SmallVector<const Stmt *, 16> NonLogOpStack;
235aca2e42cSDimitry Andric   SmallVector<const BinaryOperator *, 16> LogOpStack;
236aca2e42cSDimitry Andric 
237aca2e42cSDimitry Andric   // Hook: dataTraverseStmtPre() is invoked prior to visiting an AST Stmt node.
dataTraverseStmtPre__anone8f20fae0111::MapRegionCounters238aca2e42cSDimitry Andric   bool dataTraverseStmtPre(Stmt *S) {
239aca2e42cSDimitry Andric     /// If MC/DC is not enabled, MCDCMaxCond will be set to 0. Do nothing.
240aca2e42cSDimitry Andric     if (MCDCMaxCond == 0)
241aca2e42cSDimitry Andric       return true;
242aca2e42cSDimitry Andric 
243ac9a064cSDimitry Andric     /// At the top of the logical operator nest, reset the number of conditions,
244ac9a064cSDimitry Andric     /// also forget previously seen split nesting cases.
245ac9a064cSDimitry Andric     if (LogOpStack.empty()) {
246aca2e42cSDimitry Andric       NumCond = 0;
247ac9a064cSDimitry Andric       SplitNestedLogicalOp = false;
248ac9a064cSDimitry Andric     }
249aca2e42cSDimitry Andric 
250aca2e42cSDimitry Andric     if (const Expr *E = dyn_cast<Expr>(S)) {
251aca2e42cSDimitry Andric       const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E->IgnoreParens());
252aca2e42cSDimitry Andric       if (BinOp && BinOp->isLogicalOp()) {
253aca2e42cSDimitry Andric         /// Check for "split-nested" logical operators. This happens when a new
254aca2e42cSDimitry Andric         /// boolean expression logical-op nest is encountered within an existing
255aca2e42cSDimitry Andric         /// boolean expression, separated by a non-logical operator.  For
256aca2e42cSDimitry Andric         /// example, in "x = (a && b && c && foo(d && f))", the "d && f" case
257aca2e42cSDimitry Andric         /// starts a new boolean expression that is separated from the other
258aca2e42cSDimitry Andric         /// conditions by the operator foo(). Split-nested cases are not
259aca2e42cSDimitry Andric         /// supported by MC/DC.
260aca2e42cSDimitry Andric         SplitNestedLogicalOp = SplitNestedLogicalOp || !NonLogOpStack.empty();
261aca2e42cSDimitry Andric 
262aca2e42cSDimitry Andric         LogOpStack.push_back(BinOp);
263aca2e42cSDimitry Andric         return true;
264aca2e42cSDimitry Andric       }
265aca2e42cSDimitry Andric     }
266aca2e42cSDimitry Andric 
267aca2e42cSDimitry Andric     /// Keep track of non-logical operators. These are OK as long as we don't
268aca2e42cSDimitry Andric     /// encounter a new logical operator after seeing one.
269aca2e42cSDimitry Andric     if (!LogOpStack.empty())
270aca2e42cSDimitry Andric       NonLogOpStack.push_back(S);
271aca2e42cSDimitry Andric 
272aca2e42cSDimitry Andric     return true;
273aca2e42cSDimitry Andric   }
274aca2e42cSDimitry Andric 
275aca2e42cSDimitry Andric   // Hook: dataTraverseStmtPost() is invoked by the AST visitor after visiting
276aca2e42cSDimitry Andric   // an AST Stmt node.  MC/DC will use it to to signal when the top of a
277aca2e42cSDimitry Andric   // logical operation (boolean expression) nest is encountered.
dataTraverseStmtPost__anone8f20fae0111::MapRegionCounters278aca2e42cSDimitry Andric   bool dataTraverseStmtPost(Stmt *S) {
279aca2e42cSDimitry Andric     /// If MC/DC is not enabled, MCDCMaxCond will be set to 0. Do nothing.
280aca2e42cSDimitry Andric     if (MCDCMaxCond == 0)
281aca2e42cSDimitry Andric       return true;
282aca2e42cSDimitry Andric 
283aca2e42cSDimitry Andric     if (const Expr *E = dyn_cast<Expr>(S)) {
284aca2e42cSDimitry Andric       const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E->IgnoreParens());
285aca2e42cSDimitry Andric       if (BinOp && BinOp->isLogicalOp()) {
286aca2e42cSDimitry Andric         assert(LogOpStack.back() == BinOp);
287aca2e42cSDimitry Andric         LogOpStack.pop_back();
288aca2e42cSDimitry Andric 
289aca2e42cSDimitry Andric         /// At the top of logical operator nest:
290aca2e42cSDimitry Andric         if (LogOpStack.empty()) {
291aca2e42cSDimitry Andric           /// Was the "split-nested" logical operator case encountered?
292aca2e42cSDimitry Andric           if (SplitNestedLogicalOp) {
293aca2e42cSDimitry Andric             unsigned DiagID = Diag.getCustomDiagID(
294aca2e42cSDimitry Andric                 DiagnosticsEngine::Warning,
295aca2e42cSDimitry Andric                 "unsupported MC/DC boolean expression; "
296aca2e42cSDimitry Andric                 "contains an operation with a nested boolean expression. "
297aca2e42cSDimitry Andric                 "Expression will not be covered");
298aca2e42cSDimitry Andric             Diag.Report(S->getBeginLoc(), DiagID);
299ac9a064cSDimitry Andric             return true;
300aca2e42cSDimitry Andric           }
301aca2e42cSDimitry Andric 
302aca2e42cSDimitry Andric           /// Was the maximum number of conditions encountered?
303aca2e42cSDimitry Andric           if (NumCond > MCDCMaxCond) {
304aca2e42cSDimitry Andric             unsigned DiagID = Diag.getCustomDiagID(
305aca2e42cSDimitry Andric                 DiagnosticsEngine::Warning,
306aca2e42cSDimitry Andric                 "unsupported MC/DC boolean expression; "
307aca2e42cSDimitry Andric                 "number of conditions (%0) exceeds max (%1). "
308aca2e42cSDimitry Andric                 "Expression will not be covered");
309aca2e42cSDimitry Andric             Diag.Report(S->getBeginLoc(), DiagID) << NumCond << MCDCMaxCond;
310ac9a064cSDimitry Andric             return true;
311aca2e42cSDimitry Andric           }
312aca2e42cSDimitry Andric 
313ac9a064cSDimitry Andric           // Otherwise, allocate the Decision.
314ac9a064cSDimitry Andric           MCDCState.DecisionByStmt[BinOp].BitmapIdx = 0;
315aca2e42cSDimitry Andric         }
316aca2e42cSDimitry Andric         return true;
317aca2e42cSDimitry Andric       }
318aca2e42cSDimitry Andric     }
319aca2e42cSDimitry Andric 
320aca2e42cSDimitry Andric     if (!LogOpStack.empty())
321aca2e42cSDimitry Andric       NonLogOpStack.pop_back();
322aca2e42cSDimitry Andric 
323aca2e42cSDimitry Andric     return true;
324aca2e42cSDimitry Andric   }
325aca2e42cSDimitry Andric 
326b60736ecSDimitry Andric   /// The RHS of all logical operators gets a fresh counter in order to count
327b60736ecSDimitry Andric   /// how many times the RHS evaluates to true or false, depending on the
328b60736ecSDimitry Andric   /// semantics of the operator. This is only valid for ">= v7" of the profile
329aca2e42cSDimitry Andric   /// version so that we facilitate backward compatibility. In addition, in
330aca2e42cSDimitry Andric   /// order to use MC/DC, count the number of total LHS and RHS conditions.
VisitBinaryOperator__anone8f20fae0111::MapRegionCounters331b60736ecSDimitry Andric   bool VisitBinaryOperator(BinaryOperator *S) {
332aca2e42cSDimitry Andric     if (S->isLogicalOp()) {
333aca2e42cSDimitry Andric       if (CodeGenFunction::isInstrumentedCondition(S->getLHS()))
334aca2e42cSDimitry Andric         NumCond++;
335aca2e42cSDimitry Andric 
336aca2e42cSDimitry Andric       if (CodeGenFunction::isInstrumentedCondition(S->getRHS())) {
337b60736ecSDimitry Andric         if (ProfileVersion >= llvm::IndexedInstrProf::Version7)
338b60736ecSDimitry Andric           CounterMap[S->getRHS()] = NextCounter++;
339aca2e42cSDimitry Andric 
340aca2e42cSDimitry Andric         NumCond++;
341aca2e42cSDimitry Andric       }
342aca2e42cSDimitry Andric     }
343b60736ecSDimitry Andric     return Base::VisitBinaryOperator(S);
344b60736ecSDimitry Andric   }
345b60736ecSDimitry Andric 
VisitConditionalOperator__anone8f20fae0111::MapRegionCounters346ac9a064cSDimitry Andric   bool VisitConditionalOperator(ConditionalOperator *S) {
347ac9a064cSDimitry Andric     if (llvm::EnableSingleByteCoverage && S->getTrueExpr())
348ac9a064cSDimitry Andric       CounterMap[S->getTrueExpr()] = NextCounter++;
349ac9a064cSDimitry Andric     if (llvm::EnableSingleByteCoverage && S->getFalseExpr())
350ac9a064cSDimitry Andric       CounterMap[S->getFalseExpr()] = NextCounter++;
351ac9a064cSDimitry Andric     return Base::VisitConditionalOperator(S);
352ac9a064cSDimitry Andric   }
353ac9a064cSDimitry Andric 
354461a67faSDimitry Andric   /// Include \p S in the function hash.
VisitStmt__anone8f20fae0111::MapRegionCounters355461a67faSDimitry Andric   bool VisitStmt(Stmt *S) {
356461a67faSDimitry Andric     auto Type = updateCounterMappings(S);
357461a67faSDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
358461a67faSDimitry Andric       Type = getHashType(Hash.getHashVersion(), S);
359461a67faSDimitry Andric     if (Type != PGOHash::None)
3609f4dbff6SDimitry Andric       Hash.combine(Type);
3619f4dbff6SDimitry Andric     return true;
3629f4dbff6SDimitry Andric   }
363461a67faSDimitry Andric 
TraverseIfStmt__anone8f20fae0111::MapRegionCounters364461a67faSDimitry Andric   bool TraverseIfStmt(IfStmt *If) {
365461a67faSDimitry Andric     // If we used the V1 hash, use the default traversal.
366461a67faSDimitry Andric     if (Hash.getHashVersion() == PGO_HASH_V1)
367461a67faSDimitry Andric       return Base::TraverseIfStmt(If);
368461a67faSDimitry Andric 
369ac9a064cSDimitry Andric     // When single byte coverage mode is enabled, add a counter to then and
370ac9a064cSDimitry Andric     // else.
371ac9a064cSDimitry Andric     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
372ac9a064cSDimitry Andric     for (Stmt *CS : If->children()) {
373ac9a064cSDimitry Andric       if (!CS || NoSingleByteCoverage)
374ac9a064cSDimitry Andric         continue;
375ac9a064cSDimitry Andric       if (CS == If->getThen())
376ac9a064cSDimitry Andric         CounterMap[If->getThen()] = NextCounter++;
377ac9a064cSDimitry Andric       else if (CS == If->getElse())
378ac9a064cSDimitry Andric         CounterMap[If->getElse()] = NextCounter++;
379ac9a064cSDimitry Andric     }
380ac9a064cSDimitry Andric 
381461a67faSDimitry Andric     // Otherwise, keep track of which branch we're in while traversing.
382461a67faSDimitry Andric     VisitStmt(If);
383ac9a064cSDimitry Andric 
384461a67faSDimitry Andric     for (Stmt *CS : If->children()) {
385461a67faSDimitry Andric       if (!CS)
386461a67faSDimitry Andric         continue;
387461a67faSDimitry Andric       if (CS == If->getThen())
388461a67faSDimitry Andric         Hash.combine(PGOHash::IfThenBranch);
389461a67faSDimitry Andric       else if (CS == If->getElse())
390461a67faSDimitry Andric         Hash.combine(PGOHash::IfElseBranch);
391461a67faSDimitry Andric       TraverseStmt(CS);
392461a67faSDimitry Andric     }
393461a67faSDimitry Andric     Hash.combine(PGOHash::EndOfScope);
394461a67faSDimitry Andric     return true;
395461a67faSDimitry Andric   }
396461a67faSDimitry Andric 
TraverseWhileStmt__anone8f20fae0111::MapRegionCounters397ac9a064cSDimitry Andric   bool TraverseWhileStmt(WhileStmt *While) {
398ac9a064cSDimitry Andric     // When single byte coverage mode is enabled, add a counter to condition and
399ac9a064cSDimitry Andric     // body.
400ac9a064cSDimitry Andric     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
401ac9a064cSDimitry Andric     for (Stmt *CS : While->children()) {
402ac9a064cSDimitry Andric       if (!CS || NoSingleByteCoverage)
403ac9a064cSDimitry Andric         continue;
404ac9a064cSDimitry Andric       if (CS == While->getCond())
405ac9a064cSDimitry Andric         CounterMap[While->getCond()] = NextCounter++;
406ac9a064cSDimitry Andric       else if (CS == While->getBody())
407ac9a064cSDimitry Andric         CounterMap[While->getBody()] = NextCounter++;
408ac9a064cSDimitry Andric     }
409ac9a064cSDimitry Andric 
410ac9a064cSDimitry Andric     Base::TraverseWhileStmt(While);
411ac9a064cSDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
412ac9a064cSDimitry Andric       Hash.combine(PGOHash::EndOfScope);
413ac9a064cSDimitry Andric     return true;
414ac9a064cSDimitry Andric   }
415ac9a064cSDimitry Andric 
TraverseDoStmt__anone8f20fae0111::MapRegionCounters416ac9a064cSDimitry Andric   bool TraverseDoStmt(DoStmt *Do) {
417ac9a064cSDimitry Andric     // When single byte coverage mode is enabled, add a counter to condition and
418ac9a064cSDimitry Andric     // body.
419ac9a064cSDimitry Andric     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
420ac9a064cSDimitry Andric     for (Stmt *CS : Do->children()) {
421ac9a064cSDimitry Andric       if (!CS || NoSingleByteCoverage)
422ac9a064cSDimitry Andric         continue;
423ac9a064cSDimitry Andric       if (CS == Do->getCond())
424ac9a064cSDimitry Andric         CounterMap[Do->getCond()] = NextCounter++;
425ac9a064cSDimitry Andric       else if (CS == Do->getBody())
426ac9a064cSDimitry Andric         CounterMap[Do->getBody()] = NextCounter++;
427ac9a064cSDimitry Andric     }
428ac9a064cSDimitry Andric 
429ac9a064cSDimitry Andric     Base::TraverseDoStmt(Do);
430ac9a064cSDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
431ac9a064cSDimitry Andric       Hash.combine(PGOHash::EndOfScope);
432ac9a064cSDimitry Andric     return true;
433ac9a064cSDimitry Andric   }
434ac9a064cSDimitry Andric 
TraverseForStmt__anone8f20fae0111::MapRegionCounters435ac9a064cSDimitry Andric   bool TraverseForStmt(ForStmt *For) {
436ac9a064cSDimitry Andric     // When single byte coverage mode is enabled, add a counter to condition,
437ac9a064cSDimitry Andric     // increment and body.
438ac9a064cSDimitry Andric     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
439ac9a064cSDimitry Andric     for (Stmt *CS : For->children()) {
440ac9a064cSDimitry Andric       if (!CS || NoSingleByteCoverage)
441ac9a064cSDimitry Andric         continue;
442ac9a064cSDimitry Andric       if (CS == For->getCond())
443ac9a064cSDimitry Andric         CounterMap[For->getCond()] = NextCounter++;
444ac9a064cSDimitry Andric       else if (CS == For->getInc())
445ac9a064cSDimitry Andric         CounterMap[For->getInc()] = NextCounter++;
446ac9a064cSDimitry Andric       else if (CS == For->getBody())
447ac9a064cSDimitry Andric         CounterMap[For->getBody()] = NextCounter++;
448ac9a064cSDimitry Andric     }
449ac9a064cSDimitry Andric 
450ac9a064cSDimitry Andric     Base::TraverseForStmt(For);
451ac9a064cSDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
452ac9a064cSDimitry Andric       Hash.combine(PGOHash::EndOfScope);
453ac9a064cSDimitry Andric     return true;
454ac9a064cSDimitry Andric   }
455ac9a064cSDimitry Andric 
TraverseCXXForRangeStmt__anone8f20fae0111::MapRegionCounters456ac9a064cSDimitry Andric   bool TraverseCXXForRangeStmt(CXXForRangeStmt *ForRange) {
457ac9a064cSDimitry Andric     // When single byte coverage mode is enabled, add a counter to body.
458ac9a064cSDimitry Andric     bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
459ac9a064cSDimitry Andric     for (Stmt *CS : ForRange->children()) {
460ac9a064cSDimitry Andric       if (!CS || NoSingleByteCoverage)
461ac9a064cSDimitry Andric         continue;
462ac9a064cSDimitry Andric       if (CS == ForRange->getBody())
463ac9a064cSDimitry Andric         CounterMap[ForRange->getBody()] = NextCounter++;
464ac9a064cSDimitry Andric     }
465ac9a064cSDimitry Andric 
466ac9a064cSDimitry Andric     Base::TraverseCXXForRangeStmt(ForRange);
467ac9a064cSDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
468ac9a064cSDimitry Andric       Hash.combine(PGOHash::EndOfScope);
469ac9a064cSDimitry Andric     return true;
470ac9a064cSDimitry Andric   }
471ac9a064cSDimitry Andric 
472461a67faSDimitry Andric // If the statement type \p N is nestable, and its nesting impacts profile
473461a67faSDimitry Andric // stability, define a custom traversal which tracks the end of the statement
474461a67faSDimitry Andric // in the hash (provided we're not using the V1 hash).
475461a67faSDimitry Andric #define DEFINE_NESTABLE_TRAVERSAL(N)                                           \
476461a67faSDimitry Andric   bool Traverse##N(N *S) {                                                     \
477461a67faSDimitry Andric     Base::Traverse##N(S);                                                      \
478461a67faSDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)                                  \
479461a67faSDimitry Andric       Hash.combine(PGOHash::EndOfScope);                                       \
480461a67faSDimitry Andric     return true;                                                               \
481461a67faSDimitry Andric   }
482461a67faSDimitry Andric 
483461a67faSDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(ObjCForCollectionStmt)
DEFINE_NESTABLE_TRAVERSAL__anone8f20fae0111::MapRegionCounters484461a67faSDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXTryStmt)
485461a67faSDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXCatchStmt)
486461a67faSDimitry Andric 
487461a67faSDimitry Andric   /// Get version \p HashVersion of the PGO hash for \p S.
488461a67faSDimitry Andric   PGOHash::HashType getHashType(PGOHashVersion HashVersion, const Stmt *S) {
4899f4dbff6SDimitry Andric     switch (S->getStmtClass()) {
4909f4dbff6SDimitry Andric     default:
4919f4dbff6SDimitry Andric       break;
4929f4dbff6SDimitry Andric     case Stmt::LabelStmtClass:
4939f4dbff6SDimitry Andric       return PGOHash::LabelStmt;
4949f4dbff6SDimitry Andric     case Stmt::WhileStmtClass:
4959f4dbff6SDimitry Andric       return PGOHash::WhileStmt;
4969f4dbff6SDimitry Andric     case Stmt::DoStmtClass:
4979f4dbff6SDimitry Andric       return PGOHash::DoStmt;
4989f4dbff6SDimitry Andric     case Stmt::ForStmtClass:
4999f4dbff6SDimitry Andric       return PGOHash::ForStmt;
5009f4dbff6SDimitry Andric     case Stmt::CXXForRangeStmtClass:
5019f4dbff6SDimitry Andric       return PGOHash::CXXForRangeStmt;
5029f4dbff6SDimitry Andric     case Stmt::ObjCForCollectionStmtClass:
5039f4dbff6SDimitry Andric       return PGOHash::ObjCForCollectionStmt;
5049f4dbff6SDimitry Andric     case Stmt::SwitchStmtClass:
5059f4dbff6SDimitry Andric       return PGOHash::SwitchStmt;
5069f4dbff6SDimitry Andric     case Stmt::CaseStmtClass:
5079f4dbff6SDimitry Andric       return PGOHash::CaseStmt;
5089f4dbff6SDimitry Andric     case Stmt::DefaultStmtClass:
5099f4dbff6SDimitry Andric       return PGOHash::DefaultStmt;
5109f4dbff6SDimitry Andric     case Stmt::IfStmtClass:
5119f4dbff6SDimitry Andric       return PGOHash::IfStmt;
5129f4dbff6SDimitry Andric     case Stmt::CXXTryStmtClass:
5139f4dbff6SDimitry Andric       return PGOHash::CXXTryStmt;
5149f4dbff6SDimitry Andric     case Stmt::CXXCatchStmtClass:
5159f4dbff6SDimitry Andric       return PGOHash::CXXCatchStmt;
5169f4dbff6SDimitry Andric     case Stmt::ConditionalOperatorClass:
5179f4dbff6SDimitry Andric       return PGOHash::ConditionalOperator;
5189f4dbff6SDimitry Andric     case Stmt::BinaryConditionalOperatorClass:
5199f4dbff6SDimitry Andric       return PGOHash::BinaryConditionalOperator;
5209f4dbff6SDimitry Andric     case Stmt::BinaryOperatorClass: {
5219f4dbff6SDimitry Andric       const BinaryOperator *BO = cast<BinaryOperator>(S);
5229f4dbff6SDimitry Andric       if (BO->getOpcode() == BO_LAnd)
5239f4dbff6SDimitry Andric         return PGOHash::BinaryOperatorLAnd;
5249f4dbff6SDimitry Andric       if (BO->getOpcode() == BO_LOr)
5259f4dbff6SDimitry Andric         return PGOHash::BinaryOperatorLOr;
526cfca06d7SDimitry Andric       if (HashVersion >= PGO_HASH_V2) {
527461a67faSDimitry Andric         switch (BO->getOpcode()) {
528461a67faSDimitry Andric         default:
529461a67faSDimitry Andric           break;
530461a67faSDimitry Andric         case BO_LT:
531461a67faSDimitry Andric           return PGOHash::BinaryOperatorLT;
532461a67faSDimitry Andric         case BO_GT:
533461a67faSDimitry Andric           return PGOHash::BinaryOperatorGT;
534461a67faSDimitry Andric         case BO_LE:
535461a67faSDimitry Andric           return PGOHash::BinaryOperatorLE;
536461a67faSDimitry Andric         case BO_GE:
537461a67faSDimitry Andric           return PGOHash::BinaryOperatorGE;
538461a67faSDimitry Andric         case BO_EQ:
539461a67faSDimitry Andric           return PGOHash::BinaryOperatorEQ;
540461a67faSDimitry Andric         case BO_NE:
541461a67faSDimitry Andric           return PGOHash::BinaryOperatorNE;
542461a67faSDimitry Andric         }
543461a67faSDimitry Andric       }
5449f4dbff6SDimitry Andric       break;
5459f4dbff6SDimitry Andric     }
5469f4dbff6SDimitry Andric     }
547461a67faSDimitry Andric 
548cfca06d7SDimitry Andric     if (HashVersion >= PGO_HASH_V2) {
549461a67faSDimitry Andric       switch (S->getStmtClass()) {
550461a67faSDimitry Andric       default:
551461a67faSDimitry Andric         break;
552461a67faSDimitry Andric       case Stmt::GotoStmtClass:
553461a67faSDimitry Andric         return PGOHash::GotoStmt;
554461a67faSDimitry Andric       case Stmt::IndirectGotoStmtClass:
555461a67faSDimitry Andric         return PGOHash::IndirectGotoStmt;
556461a67faSDimitry Andric       case Stmt::BreakStmtClass:
557461a67faSDimitry Andric         return PGOHash::BreakStmt;
558461a67faSDimitry Andric       case Stmt::ContinueStmtClass:
559461a67faSDimitry Andric         return PGOHash::ContinueStmt;
560461a67faSDimitry Andric       case Stmt::ReturnStmtClass:
561461a67faSDimitry Andric         return PGOHash::ReturnStmt;
562461a67faSDimitry Andric       case Stmt::CXXThrowExprClass:
563461a67faSDimitry Andric         return PGOHash::ThrowExpr;
564461a67faSDimitry Andric       case Stmt::UnaryOperatorClass: {
565461a67faSDimitry Andric         const UnaryOperator *UO = cast<UnaryOperator>(S);
566461a67faSDimitry Andric         if (UO->getOpcode() == UO_LNot)
567461a67faSDimitry Andric           return PGOHash::UnaryOperatorLNot;
568461a67faSDimitry Andric         break;
569461a67faSDimitry Andric       }
570461a67faSDimitry Andric       }
571461a67faSDimitry Andric     }
572461a67faSDimitry Andric 
5739f4dbff6SDimitry Andric     return PGOHash::None;
5749f4dbff6SDimitry Andric   }
5759f4dbff6SDimitry Andric };
5769f4dbff6SDimitry Andric 
5779f4dbff6SDimitry Andric /// A StmtVisitor that propagates the raw counts through the AST and
5789f4dbff6SDimitry Andric /// records the count at statements where the value may change.
5799f4dbff6SDimitry Andric struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
5809f4dbff6SDimitry Andric   /// PGO state.
5819f4dbff6SDimitry Andric   CodeGenPGO &PGO;
5829f4dbff6SDimitry Andric 
5839f4dbff6SDimitry Andric   /// A flag that is set when the current count should be recorded on the
5849f4dbff6SDimitry Andric   /// next statement, such as at the exit of a loop.
5859f4dbff6SDimitry Andric   bool RecordNextStmtCount;
5869f4dbff6SDimitry Andric 
5875e20cdd8SDimitry Andric   /// The count at the current location in the traversal.
5885e20cdd8SDimitry Andric   uint64_t CurrentCount;
5895e20cdd8SDimitry Andric 
5909f4dbff6SDimitry Andric   /// The map of statements to count values.
5919f4dbff6SDimitry Andric   llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
5929f4dbff6SDimitry Andric 
5939f4dbff6SDimitry Andric   /// BreakContinueStack - Keep counts of breaks and continues inside loops.
5949f4dbff6SDimitry Andric   struct BreakContinue {
595b1c73532SDimitry Andric     uint64_t BreakCount = 0;
596b1c73532SDimitry Andric     uint64_t ContinueCount = 0;
597b1c73532SDimitry Andric     BreakContinue() = default;
5989f4dbff6SDimitry Andric   };
5999f4dbff6SDimitry Andric   SmallVector<BreakContinue, 8> BreakContinueStack;
6009f4dbff6SDimitry Andric 
ComputeRegionCounts__anone8f20fae0111::ComputeRegionCounts6019f4dbff6SDimitry Andric   ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
6029f4dbff6SDimitry Andric                       CodeGenPGO &PGO)
6039f4dbff6SDimitry Andric       : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
6049f4dbff6SDimitry Andric 
RecordStmtCount__anone8f20fae0111::ComputeRegionCounts6059f4dbff6SDimitry Andric   void RecordStmtCount(const Stmt *S) {
6069f4dbff6SDimitry Andric     if (RecordNextStmtCount) {
6075e20cdd8SDimitry Andric       CountMap[S] = CurrentCount;
6089f4dbff6SDimitry Andric       RecordNextStmtCount = false;
6099f4dbff6SDimitry Andric     }
6109f4dbff6SDimitry Andric   }
6119f4dbff6SDimitry Andric 
6125e20cdd8SDimitry Andric   /// Set and return the current count.
setCount__anone8f20fae0111::ComputeRegionCounts6135e20cdd8SDimitry Andric   uint64_t setCount(uint64_t Count) {
6145e20cdd8SDimitry Andric     CurrentCount = Count;
6155e20cdd8SDimitry Andric     return Count;
6165e20cdd8SDimitry Andric   }
6175e20cdd8SDimitry Andric 
VisitStmt__anone8f20fae0111::ComputeRegionCounts6189f4dbff6SDimitry Andric   void VisitStmt(const Stmt *S) {
6199f4dbff6SDimitry Andric     RecordStmtCount(S);
620c192b3dcSDimitry Andric     for (const Stmt *Child : S->children())
621c192b3dcSDimitry Andric       if (Child)
622c192b3dcSDimitry Andric         this->Visit(Child);
6239f4dbff6SDimitry Andric   }
6249f4dbff6SDimitry Andric 
VisitFunctionDecl__anone8f20fae0111::ComputeRegionCounts6259f4dbff6SDimitry Andric   void VisitFunctionDecl(const FunctionDecl *D) {
6269f4dbff6SDimitry Andric     // Counter tracks entry to the function body.
6275e20cdd8SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
6285e20cdd8SDimitry Andric     CountMap[D->getBody()] = BodyCount;
6299f4dbff6SDimitry Andric     Visit(D->getBody());
6309f4dbff6SDimitry Andric   }
6319f4dbff6SDimitry Andric 
6329f4dbff6SDimitry Andric   // Skip lambda expressions. We visit these as FunctionDecls when we're
6339f4dbff6SDimitry Andric   // generating them and aren't interested in the body when generating a
6349f4dbff6SDimitry Andric   // parent context.
VisitLambdaExpr__anone8f20fae0111::ComputeRegionCounts6359f4dbff6SDimitry Andric   void VisitLambdaExpr(const LambdaExpr *LE) {}
6369f4dbff6SDimitry Andric 
VisitCapturedDecl__anone8f20fae0111::ComputeRegionCounts6379f4dbff6SDimitry Andric   void VisitCapturedDecl(const CapturedDecl *D) {
6389f4dbff6SDimitry Andric     // Counter tracks entry to the capture body.
6395e20cdd8SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
6405e20cdd8SDimitry Andric     CountMap[D->getBody()] = BodyCount;
6419f4dbff6SDimitry Andric     Visit(D->getBody());
6429f4dbff6SDimitry Andric   }
6439f4dbff6SDimitry Andric 
VisitObjCMethodDecl__anone8f20fae0111::ComputeRegionCounts6449f4dbff6SDimitry Andric   void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
6459f4dbff6SDimitry Andric     // Counter tracks entry to the method body.
6465e20cdd8SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
6475e20cdd8SDimitry Andric     CountMap[D->getBody()] = BodyCount;
6489f4dbff6SDimitry Andric     Visit(D->getBody());
6499f4dbff6SDimitry Andric   }
6509f4dbff6SDimitry Andric 
VisitBlockDecl__anone8f20fae0111::ComputeRegionCounts6519f4dbff6SDimitry Andric   void VisitBlockDecl(const BlockDecl *D) {
6529f4dbff6SDimitry Andric     // Counter tracks entry to the block body.
6535e20cdd8SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
6545e20cdd8SDimitry Andric     CountMap[D->getBody()] = BodyCount;
6559f4dbff6SDimitry Andric     Visit(D->getBody());
6569f4dbff6SDimitry Andric   }
6579f4dbff6SDimitry Andric 
VisitReturnStmt__anone8f20fae0111::ComputeRegionCounts6589f4dbff6SDimitry Andric   void VisitReturnStmt(const ReturnStmt *S) {
6599f4dbff6SDimitry Andric     RecordStmtCount(S);
6609f4dbff6SDimitry Andric     if (S->getRetValue())
6619f4dbff6SDimitry Andric       Visit(S->getRetValue());
6625e20cdd8SDimitry Andric     CurrentCount = 0;
6635e20cdd8SDimitry Andric     RecordNextStmtCount = true;
6645e20cdd8SDimitry Andric   }
6655e20cdd8SDimitry Andric 
VisitCXXThrowExpr__anone8f20fae0111::ComputeRegionCounts6665e20cdd8SDimitry Andric   void VisitCXXThrowExpr(const CXXThrowExpr *E) {
6675e20cdd8SDimitry Andric     RecordStmtCount(E);
6685e20cdd8SDimitry Andric     if (E->getSubExpr())
6695e20cdd8SDimitry Andric       Visit(E->getSubExpr());
6705e20cdd8SDimitry Andric     CurrentCount = 0;
6719f4dbff6SDimitry Andric     RecordNextStmtCount = true;
6729f4dbff6SDimitry Andric   }
6739f4dbff6SDimitry Andric 
VisitGotoStmt__anone8f20fae0111::ComputeRegionCounts6749f4dbff6SDimitry Andric   void VisitGotoStmt(const GotoStmt *S) {
6759f4dbff6SDimitry Andric     RecordStmtCount(S);
6765e20cdd8SDimitry Andric     CurrentCount = 0;
6779f4dbff6SDimitry Andric     RecordNextStmtCount = true;
6789f4dbff6SDimitry Andric   }
6799f4dbff6SDimitry Andric 
VisitLabelStmt__anone8f20fae0111::ComputeRegionCounts6809f4dbff6SDimitry Andric   void VisitLabelStmt(const LabelStmt *S) {
6819f4dbff6SDimitry Andric     RecordNextStmtCount = false;
6829f4dbff6SDimitry Andric     // Counter tracks the block following the label.
6835e20cdd8SDimitry Andric     uint64_t BlockCount = setCount(PGO.getRegionCount(S));
6845e20cdd8SDimitry Andric     CountMap[S] = BlockCount;
6859f4dbff6SDimitry Andric     Visit(S->getSubStmt());
6869f4dbff6SDimitry Andric   }
6879f4dbff6SDimitry Andric 
VisitBreakStmt__anone8f20fae0111::ComputeRegionCounts6889f4dbff6SDimitry Andric   void VisitBreakStmt(const BreakStmt *S) {
6899f4dbff6SDimitry Andric     RecordStmtCount(S);
6909f4dbff6SDimitry Andric     assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
6915e20cdd8SDimitry Andric     BreakContinueStack.back().BreakCount += CurrentCount;
6925e20cdd8SDimitry Andric     CurrentCount = 0;
6939f4dbff6SDimitry Andric     RecordNextStmtCount = true;
6949f4dbff6SDimitry Andric   }
6959f4dbff6SDimitry Andric 
VisitContinueStmt__anone8f20fae0111::ComputeRegionCounts6969f4dbff6SDimitry Andric   void VisitContinueStmt(const ContinueStmt *S) {
6979f4dbff6SDimitry Andric     RecordStmtCount(S);
6989f4dbff6SDimitry Andric     assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
6995e20cdd8SDimitry Andric     BreakContinueStack.back().ContinueCount += CurrentCount;
7005e20cdd8SDimitry Andric     CurrentCount = 0;
7019f4dbff6SDimitry Andric     RecordNextStmtCount = true;
7029f4dbff6SDimitry Andric   }
7039f4dbff6SDimitry Andric 
VisitWhileStmt__anone8f20fae0111::ComputeRegionCounts7049f4dbff6SDimitry Andric   void VisitWhileStmt(const WhileStmt *S) {
7059f4dbff6SDimitry Andric     RecordStmtCount(S);
7065e20cdd8SDimitry Andric     uint64_t ParentCount = CurrentCount;
7075e20cdd8SDimitry Andric 
7089f4dbff6SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
7099f4dbff6SDimitry Andric     // Visit the body region first so the break/continue adjustments can be
7109f4dbff6SDimitry Andric     // included when visiting the condition.
7115e20cdd8SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
7125e20cdd8SDimitry Andric     CountMap[S->getBody()] = CurrentCount;
7139f4dbff6SDimitry Andric     Visit(S->getBody());
7145e20cdd8SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
7159f4dbff6SDimitry Andric 
7169f4dbff6SDimitry Andric     // ...then go back and propagate counts through the condition. The count
7179f4dbff6SDimitry Andric     // at the start of the condition is the sum of the incoming edges,
7189f4dbff6SDimitry Andric     // the backedge from the end of the loop body, and the edges from
7199f4dbff6SDimitry Andric     // continue statements.
7209f4dbff6SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
7215e20cdd8SDimitry Andric     uint64_t CondCount =
7225e20cdd8SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
7235e20cdd8SDimitry Andric     CountMap[S->getCond()] = CondCount;
7249f4dbff6SDimitry Andric     Visit(S->getCond());
7255e20cdd8SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
7269f4dbff6SDimitry Andric     RecordNextStmtCount = true;
7279f4dbff6SDimitry Andric   }
7289f4dbff6SDimitry Andric 
VisitDoStmt__anone8f20fae0111::ComputeRegionCounts7299f4dbff6SDimitry Andric   void VisitDoStmt(const DoStmt *S) {
7309f4dbff6SDimitry Andric     RecordStmtCount(S);
7315e20cdd8SDimitry Andric     uint64_t LoopCount = PGO.getRegionCount(S);
7325e20cdd8SDimitry Andric 
7339f4dbff6SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
7345e20cdd8SDimitry Andric     // The count doesn't include the fallthrough from the parent scope. Add it.
7355e20cdd8SDimitry Andric     uint64_t BodyCount = setCount(LoopCount + CurrentCount);
7365e20cdd8SDimitry Andric     CountMap[S->getBody()] = BodyCount;
7379f4dbff6SDimitry Andric     Visit(S->getBody());
7385e20cdd8SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
7399f4dbff6SDimitry Andric 
7409f4dbff6SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
7419f4dbff6SDimitry Andric     // The count at the start of the condition is equal to the count at the
7425e20cdd8SDimitry Andric     // end of the body, plus any continues.
7435e20cdd8SDimitry Andric     uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount);
7445e20cdd8SDimitry Andric     CountMap[S->getCond()] = CondCount;
7459f4dbff6SDimitry Andric     Visit(S->getCond());
7465e20cdd8SDimitry Andric     setCount(BC.BreakCount + CondCount - LoopCount);
7479f4dbff6SDimitry Andric     RecordNextStmtCount = true;
7489f4dbff6SDimitry Andric   }
7499f4dbff6SDimitry Andric 
VisitForStmt__anone8f20fae0111::ComputeRegionCounts7509f4dbff6SDimitry Andric   void VisitForStmt(const ForStmt *S) {
7519f4dbff6SDimitry Andric     RecordStmtCount(S);
7529f4dbff6SDimitry Andric     if (S->getInit())
7539f4dbff6SDimitry Andric       Visit(S->getInit());
7545e20cdd8SDimitry Andric 
7555e20cdd8SDimitry Andric     uint64_t ParentCount = CurrentCount;
7565e20cdd8SDimitry Andric 
7579f4dbff6SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
7589f4dbff6SDimitry Andric     // Visit the body region first. (This is basically the same as a while
7599f4dbff6SDimitry Andric     // loop; see further comments in VisitWhileStmt.)
7605e20cdd8SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
7615e20cdd8SDimitry Andric     CountMap[S->getBody()] = BodyCount;
7629f4dbff6SDimitry Andric     Visit(S->getBody());
7635e20cdd8SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
7645e20cdd8SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
7659f4dbff6SDimitry Andric 
7669f4dbff6SDimitry Andric     // The increment is essentially part of the body but it needs to include
7679f4dbff6SDimitry Andric     // the count for all the continue statements.
7689f4dbff6SDimitry Andric     if (S->getInc()) {
7695e20cdd8SDimitry Andric       uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
7705e20cdd8SDimitry Andric       CountMap[S->getInc()] = IncCount;
7719f4dbff6SDimitry Andric       Visit(S->getInc());
7729f4dbff6SDimitry Andric     }
7739f4dbff6SDimitry Andric 
7749f4dbff6SDimitry Andric     // ...then go back and propagate counts through the condition.
7755e20cdd8SDimitry Andric     uint64_t CondCount =
7765e20cdd8SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
7779f4dbff6SDimitry Andric     if (S->getCond()) {
7785e20cdd8SDimitry Andric       CountMap[S->getCond()] = CondCount;
7799f4dbff6SDimitry Andric       Visit(S->getCond());
7809f4dbff6SDimitry Andric     }
7815e20cdd8SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
7829f4dbff6SDimitry Andric     RecordNextStmtCount = true;
7839f4dbff6SDimitry Andric   }
7849f4dbff6SDimitry Andric 
VisitCXXForRangeStmt__anone8f20fae0111::ComputeRegionCounts7859f4dbff6SDimitry Andric   void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
7869f4dbff6SDimitry Andric     RecordStmtCount(S);
787676fbe81SDimitry Andric     if (S->getInit())
788676fbe81SDimitry Andric       Visit(S->getInit());
7895e20cdd8SDimitry Andric     Visit(S->getLoopVarStmt());
7909f4dbff6SDimitry Andric     Visit(S->getRangeStmt());
7912b6b257fSDimitry Andric     Visit(S->getBeginStmt());
7922b6b257fSDimitry Andric     Visit(S->getEndStmt());
7935e20cdd8SDimitry Andric 
7945e20cdd8SDimitry Andric     uint64_t ParentCount = CurrentCount;
7959f4dbff6SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
7969f4dbff6SDimitry Andric     // Visit the body region first. (This is basically the same as a while
7979f4dbff6SDimitry Andric     // loop; see further comments in VisitWhileStmt.)
7985e20cdd8SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
7995e20cdd8SDimitry Andric     CountMap[S->getBody()] = BodyCount;
8009f4dbff6SDimitry Andric     Visit(S->getBody());
8015e20cdd8SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
8025e20cdd8SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
8039f4dbff6SDimitry Andric 
8049f4dbff6SDimitry Andric     // The increment is essentially part of the body but it needs to include
8059f4dbff6SDimitry Andric     // the count for all the continue statements.
8065e20cdd8SDimitry Andric     uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
8075e20cdd8SDimitry Andric     CountMap[S->getInc()] = IncCount;
8089f4dbff6SDimitry Andric     Visit(S->getInc());
8099f4dbff6SDimitry Andric 
8109f4dbff6SDimitry Andric     // ...then go back and propagate counts through the condition.
8115e20cdd8SDimitry Andric     uint64_t CondCount =
8125e20cdd8SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
8135e20cdd8SDimitry Andric     CountMap[S->getCond()] = CondCount;
8149f4dbff6SDimitry Andric     Visit(S->getCond());
8155e20cdd8SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
8169f4dbff6SDimitry Andric     RecordNextStmtCount = true;
8179f4dbff6SDimitry Andric   }
8189f4dbff6SDimitry Andric 
VisitObjCForCollectionStmt__anone8f20fae0111::ComputeRegionCounts8199f4dbff6SDimitry Andric   void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
8209f4dbff6SDimitry Andric     RecordStmtCount(S);
8219f4dbff6SDimitry Andric     Visit(S->getElement());
8225e20cdd8SDimitry Andric     uint64_t ParentCount = CurrentCount;
8239f4dbff6SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
8245e20cdd8SDimitry Andric     // Counter tracks the body of the loop.
8255e20cdd8SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
8265e20cdd8SDimitry Andric     CountMap[S->getBody()] = BodyCount;
8279f4dbff6SDimitry Andric     Visit(S->getBody());
8285e20cdd8SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
8299f4dbff6SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
8305e20cdd8SDimitry Andric 
8315e20cdd8SDimitry Andric     setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount -
8325e20cdd8SDimitry Andric              BodyCount);
8339f4dbff6SDimitry Andric     RecordNextStmtCount = true;
8349f4dbff6SDimitry Andric   }
8359f4dbff6SDimitry Andric 
VisitSwitchStmt__anone8f20fae0111::ComputeRegionCounts8369f4dbff6SDimitry Andric   void VisitSwitchStmt(const SwitchStmt *S) {
8379f4dbff6SDimitry Andric     RecordStmtCount(S);
838bab175ecSDimitry Andric     if (S->getInit())
839bab175ecSDimitry Andric       Visit(S->getInit());
8409f4dbff6SDimitry Andric     Visit(S->getCond());
8415e20cdd8SDimitry Andric     CurrentCount = 0;
8429f4dbff6SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
8439f4dbff6SDimitry Andric     Visit(S->getBody());
8449f4dbff6SDimitry Andric     // If the switch is inside a loop, add the continue counts.
8459f4dbff6SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
8469f4dbff6SDimitry Andric     if (!BreakContinueStack.empty())
8479f4dbff6SDimitry Andric       BreakContinueStack.back().ContinueCount += BC.ContinueCount;
8489f4dbff6SDimitry Andric     // Counter tracks the exit block of the switch.
8495e20cdd8SDimitry Andric     setCount(PGO.getRegionCount(S));
8509f4dbff6SDimitry Andric     RecordNextStmtCount = true;
8519f4dbff6SDimitry Andric   }
8529f4dbff6SDimitry Andric 
VisitSwitchCase__anone8f20fae0111::ComputeRegionCounts8535e20cdd8SDimitry Andric   void VisitSwitchCase(const SwitchCase *S) {
8549f4dbff6SDimitry Andric     RecordNextStmtCount = false;
8559f4dbff6SDimitry Andric     // Counter for this particular case. This counts only jumps from the
8569f4dbff6SDimitry Andric     // switch header and does not include fallthrough from the case before
8579f4dbff6SDimitry Andric     // this one.
8585e20cdd8SDimitry Andric     uint64_t CaseCount = PGO.getRegionCount(S);
8595e20cdd8SDimitry Andric     setCount(CurrentCount + CaseCount);
8605e20cdd8SDimitry Andric     // We need the count without fallthrough in the mapping, so it's more useful
8615e20cdd8SDimitry Andric     // for branch probabilities.
8625e20cdd8SDimitry Andric     CountMap[S] = CaseCount;
8639f4dbff6SDimitry Andric     RecordNextStmtCount = true;
8649f4dbff6SDimitry Andric     Visit(S->getSubStmt());
8659f4dbff6SDimitry Andric   }
8669f4dbff6SDimitry Andric 
VisitIfStmt__anone8f20fae0111::ComputeRegionCounts8679f4dbff6SDimitry Andric   void VisitIfStmt(const IfStmt *S) {
8689f4dbff6SDimitry Andric     RecordStmtCount(S);
869c0981da4SDimitry Andric 
870c0981da4SDimitry Andric     if (S->isConsteval()) {
871c0981da4SDimitry Andric       const Stmt *Stm = S->isNegatedConsteval() ? S->getThen() : S->getElse();
872c0981da4SDimitry Andric       if (Stm)
873c0981da4SDimitry Andric         Visit(Stm);
874c0981da4SDimitry Andric       return;
875c0981da4SDimitry Andric     }
876c0981da4SDimitry Andric 
8775e20cdd8SDimitry Andric     uint64_t ParentCount = CurrentCount;
878bab175ecSDimitry Andric     if (S->getInit())
879bab175ecSDimitry Andric       Visit(S->getInit());
8809f4dbff6SDimitry Andric     Visit(S->getCond());
8819f4dbff6SDimitry Andric 
8825e20cdd8SDimitry Andric     // Counter tracks the "then" part of an if statement. The count for
8835e20cdd8SDimitry Andric     // the "else" part, if it exists, will be calculated from this counter.
8845e20cdd8SDimitry Andric     uint64_t ThenCount = setCount(PGO.getRegionCount(S));
8855e20cdd8SDimitry Andric     CountMap[S->getThen()] = ThenCount;
8869f4dbff6SDimitry Andric     Visit(S->getThen());
8875e20cdd8SDimitry Andric     uint64_t OutCount = CurrentCount;
8889f4dbff6SDimitry Andric 
8895e20cdd8SDimitry Andric     uint64_t ElseCount = ParentCount - ThenCount;
8909f4dbff6SDimitry Andric     if (S->getElse()) {
8915e20cdd8SDimitry Andric       setCount(ElseCount);
8925e20cdd8SDimitry Andric       CountMap[S->getElse()] = ElseCount;
8939f4dbff6SDimitry Andric       Visit(S->getElse());
8945e20cdd8SDimitry Andric       OutCount += CurrentCount;
8955e20cdd8SDimitry Andric     } else
8965e20cdd8SDimitry Andric       OutCount += ElseCount;
8975e20cdd8SDimitry Andric     setCount(OutCount);
8989f4dbff6SDimitry Andric     RecordNextStmtCount = true;
8999f4dbff6SDimitry Andric   }
9009f4dbff6SDimitry Andric 
VisitCXXTryStmt__anone8f20fae0111::ComputeRegionCounts9019f4dbff6SDimitry Andric   void VisitCXXTryStmt(const CXXTryStmt *S) {
9029f4dbff6SDimitry Andric     RecordStmtCount(S);
9039f4dbff6SDimitry Andric     Visit(S->getTryBlock());
9049f4dbff6SDimitry Andric     for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
9059f4dbff6SDimitry Andric       Visit(S->getHandler(I));
9069f4dbff6SDimitry Andric     // Counter tracks the continuation block of the try statement.
9075e20cdd8SDimitry Andric     setCount(PGO.getRegionCount(S));
9089f4dbff6SDimitry Andric     RecordNextStmtCount = true;
9099f4dbff6SDimitry Andric   }
9109f4dbff6SDimitry Andric 
VisitCXXCatchStmt__anone8f20fae0111::ComputeRegionCounts9119f4dbff6SDimitry Andric   void VisitCXXCatchStmt(const CXXCatchStmt *S) {
9129f4dbff6SDimitry Andric     RecordNextStmtCount = false;
9139f4dbff6SDimitry Andric     // Counter tracks the catch statement's handler block.
9145e20cdd8SDimitry Andric     uint64_t CatchCount = setCount(PGO.getRegionCount(S));
9155e20cdd8SDimitry Andric     CountMap[S] = CatchCount;
9169f4dbff6SDimitry Andric     Visit(S->getHandlerBlock());
9179f4dbff6SDimitry Andric   }
9189f4dbff6SDimitry Andric 
VisitAbstractConditionalOperator__anone8f20fae0111::ComputeRegionCounts9195e20cdd8SDimitry Andric   void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
9209f4dbff6SDimitry Andric     RecordStmtCount(E);
9215e20cdd8SDimitry Andric     uint64_t ParentCount = CurrentCount;
9229f4dbff6SDimitry Andric     Visit(E->getCond());
9239f4dbff6SDimitry Andric 
9245e20cdd8SDimitry Andric     // Counter tracks the "true" part of a conditional operator. The
9255e20cdd8SDimitry Andric     // count in the "false" part will be calculated from this counter.
9265e20cdd8SDimitry Andric     uint64_t TrueCount = setCount(PGO.getRegionCount(E));
9275e20cdd8SDimitry Andric     CountMap[E->getTrueExpr()] = TrueCount;
9289f4dbff6SDimitry Andric     Visit(E->getTrueExpr());
9295e20cdd8SDimitry Andric     uint64_t OutCount = CurrentCount;
9309f4dbff6SDimitry Andric 
9315e20cdd8SDimitry Andric     uint64_t FalseCount = setCount(ParentCount - TrueCount);
9325e20cdd8SDimitry Andric     CountMap[E->getFalseExpr()] = FalseCount;
9339f4dbff6SDimitry Andric     Visit(E->getFalseExpr());
9345e20cdd8SDimitry Andric     OutCount += CurrentCount;
9359f4dbff6SDimitry Andric 
9365e20cdd8SDimitry Andric     setCount(OutCount);
9379f4dbff6SDimitry Andric     RecordNextStmtCount = true;
9389f4dbff6SDimitry Andric   }
9399f4dbff6SDimitry Andric 
VisitBinLAnd__anone8f20fae0111::ComputeRegionCounts9409f4dbff6SDimitry Andric   void VisitBinLAnd(const BinaryOperator *E) {
9419f4dbff6SDimitry Andric     RecordStmtCount(E);
9425e20cdd8SDimitry Andric     uint64_t ParentCount = CurrentCount;
9439f4dbff6SDimitry Andric     Visit(E->getLHS());
9445e20cdd8SDimitry Andric     // Counter tracks the right hand side of a logical and operator.
9455e20cdd8SDimitry Andric     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
9465e20cdd8SDimitry Andric     CountMap[E->getRHS()] = RHSCount;
9479f4dbff6SDimitry Andric     Visit(E->getRHS());
9485e20cdd8SDimitry Andric     setCount(ParentCount + RHSCount - CurrentCount);
9499f4dbff6SDimitry Andric     RecordNextStmtCount = true;
9509f4dbff6SDimitry Andric   }
9519f4dbff6SDimitry Andric 
VisitBinLOr__anone8f20fae0111::ComputeRegionCounts9529f4dbff6SDimitry Andric   void VisitBinLOr(const BinaryOperator *E) {
9539f4dbff6SDimitry Andric     RecordStmtCount(E);
9545e20cdd8SDimitry Andric     uint64_t ParentCount = CurrentCount;
9559f4dbff6SDimitry Andric     Visit(E->getLHS());
9565e20cdd8SDimitry Andric     // Counter tracks the right hand side of a logical or operator.
9575e20cdd8SDimitry Andric     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
9585e20cdd8SDimitry Andric     CountMap[E->getRHS()] = RHSCount;
9599f4dbff6SDimitry Andric     Visit(E->getRHS());
9605e20cdd8SDimitry Andric     setCount(ParentCount + RHSCount - CurrentCount);
9619f4dbff6SDimitry Andric     RecordNextStmtCount = true;
9629f4dbff6SDimitry Andric   }
9639f4dbff6SDimitry Andric };
96445b53394SDimitry Andric } // end anonymous namespace
9659f4dbff6SDimitry Andric 
combine(HashType Type)9669f4dbff6SDimitry Andric void PGOHash::combine(HashType Type) {
9679f4dbff6SDimitry Andric   // Check that we never combine 0 and only have six bits.
9689f4dbff6SDimitry Andric   assert(Type && "Hash is invalid: unexpected type 0");
9699f4dbff6SDimitry Andric   assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
9709f4dbff6SDimitry Andric 
9719f4dbff6SDimitry Andric   // Pass through MD5 if enough work has built up.
9729f4dbff6SDimitry Andric   if (Count && Count % NumTypesPerWord == 0) {
9739f4dbff6SDimitry Andric     using namespace llvm::support;
974b1c73532SDimitry Andric     uint64_t Swapped =
975b1c73532SDimitry Andric         endian::byte_swap<uint64_t, llvm::endianness::little>(Working);
976e3b55780SDimitry Andric     MD5.update(llvm::ArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
9779f4dbff6SDimitry Andric     Working = 0;
9789f4dbff6SDimitry Andric   }
9799f4dbff6SDimitry Andric 
9809f4dbff6SDimitry Andric   // Accumulate the current type.
9819f4dbff6SDimitry Andric   ++Count;
9829f4dbff6SDimitry Andric   Working = Working << NumBitsPerType | Type;
9839f4dbff6SDimitry Andric }
9849f4dbff6SDimitry Andric 
finalize()9859f4dbff6SDimitry Andric uint64_t PGOHash::finalize() {
9869f4dbff6SDimitry Andric   // Use Working as the hash directly if we never used MD5.
9879f4dbff6SDimitry Andric   if (Count <= NumTypesPerWord)
9889f4dbff6SDimitry Andric     // No need to byte swap here, since none of the math was endian-dependent.
9899f4dbff6SDimitry Andric     // This number will be byte-swapped as required on endianness transitions,
9909f4dbff6SDimitry Andric     // so we will see the same value on the other side.
9919f4dbff6SDimitry Andric     return Working;
9929f4dbff6SDimitry Andric 
9939f4dbff6SDimitry Andric   // Check for remaining work in Working.
994cfca06d7SDimitry Andric   if (Working) {
995cfca06d7SDimitry Andric     // Keep the buggy behavior from v1 and v2 for backward-compatibility. This
996cfca06d7SDimitry Andric     // is buggy because it converts a uint64_t into an array of uint8_t.
997cfca06d7SDimitry Andric     if (HashVersion < PGO_HASH_V3) {
998cfca06d7SDimitry Andric       MD5.update({(uint8_t)Working});
999cfca06d7SDimitry Andric     } else {
1000cfca06d7SDimitry Andric       using namespace llvm::support;
1001b1c73532SDimitry Andric       uint64_t Swapped =
1002b1c73532SDimitry Andric           endian::byte_swap<uint64_t, llvm::endianness::little>(Working);
1003e3b55780SDimitry Andric       MD5.update(llvm::ArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
1004cfca06d7SDimitry Andric     }
1005cfca06d7SDimitry Andric   }
10069f4dbff6SDimitry Andric 
10079f4dbff6SDimitry Andric   // Finalize the MD5 and return the hash.
10089f4dbff6SDimitry Andric   llvm::MD5::MD5Result Result;
10099f4dbff6SDimitry Andric   MD5.final(Result);
10107442d6faSDimitry Andric   return Result.low();
10119f4dbff6SDimitry Andric }
10129f4dbff6SDimitry Andric 
assignRegionCounters(GlobalDecl GD,llvm::Function * Fn)101345b53394SDimitry Andric void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
101445b53394SDimitry Andric   const Decl *D = GD.getDecl();
1015cf1b4019SDimitry Andric   if (!D->hasBody())
1016cf1b4019SDimitry Andric     return;
1017cf1b4019SDimitry Andric 
1018b60736ecSDimitry Andric   // Skip CUDA/HIP kernel launch stub functions.
1019b60736ecSDimitry Andric   if (CGM.getLangOpts().CUDA && !CGM.getLangOpts().CUDAIsDevice &&
1020b60736ecSDimitry Andric       D->hasAttr<CUDAGlobalAttr>())
1021b60736ecSDimitry Andric     return;
1022b60736ecSDimitry Andric 
10232b6b257fSDimitry Andric   bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
10249f4dbff6SDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
10259f4dbff6SDimitry Andric   if (!InstrumentRegions && !PGOReader)
10269f4dbff6SDimitry Andric     return;
10279f4dbff6SDimitry Andric   if (D->isImplicit())
10289f4dbff6SDimitry Andric     return;
102945b53394SDimitry Andric   // Constructors and destructors may be represented by several functions in IR.
103045b53394SDimitry Andric   // If so, instrument only base variant, others are implemented by delegation
103145b53394SDimitry Andric   // to the base one, it would be counted twice otherwise.
10327442d6faSDimitry Andric   if (CGM.getTarget().getCXXABI().hasConstructorVariants()) {
10337442d6faSDimitry Andric     if (const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
10347442d6faSDimitry Andric       if (GD.getCtorType() != Ctor_Base &&
10357442d6faSDimitry Andric           CodeGenFunction::IsConstructorDelegationValid(CCD))
103645b53394SDimitry Andric         return;
103745b53394SDimitry Andric   }
103822989816SDimitry Andric   if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
103922989816SDimitry Andric     return;
104022989816SDimitry Andric 
1041344a3780SDimitry Andric   CGM.ClearUnusedCoverageMapping(D);
1042b60736ecSDimitry Andric   if (Fn->hasFnAttribute(llvm::Attribute::NoProfile))
1043b60736ecSDimitry Andric     return;
1044e3b55780SDimitry Andric   if (Fn->hasFnAttribute(llvm::Attribute::SkipProfile))
1045e3b55780SDimitry Andric     return;
1046b60736ecSDimitry Andric 
1047ac9a064cSDimitry Andric   SourceManager &SM = CGM.getContext().getSourceManager();
1048ac9a064cSDimitry Andric   if (!llvm::coverage::SystemHeadersCoverage &&
1049ac9a064cSDimitry Andric       SM.isInSystemHeader(D->getLocation()))
1050ac9a064cSDimitry Andric     return;
1051ac9a064cSDimitry Andric 
10529f4dbff6SDimitry Andric   setFuncName(Fn);
10539f4dbff6SDimitry Andric 
10549f4dbff6SDimitry Andric   mapRegionCounters(D);
105506d4ba38SDimitry Andric   if (CGM.getCodeGenOpts().CoverageMapping)
105606d4ba38SDimitry Andric     emitCounterRegionMapping(D);
10579f4dbff6SDimitry Andric   if (PGOReader) {
10589f4dbff6SDimitry Andric     loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
10599f4dbff6SDimitry Andric     computeRegionCounts(D);
10609f4dbff6SDimitry Andric     applyFunctionAttributes(PGOReader, Fn);
10619f4dbff6SDimitry Andric   }
10629f4dbff6SDimitry Andric }
10639f4dbff6SDimitry Andric 
mapRegionCounters(const Decl * D)10649f4dbff6SDimitry Andric void CodeGenPGO::mapRegionCounters(const Decl *D) {
1065461a67faSDimitry Andric   // Use the latest hash version when inserting instrumentation, but use the
1066461a67faSDimitry Andric   // version in the indexed profile if we're reading PGO data.
1067461a67faSDimitry Andric   PGOHashVersion HashVersion = PGO_HASH_LATEST;
1068b60736ecSDimitry Andric   uint64_t ProfileVersion = llvm::IndexedInstrProf::Version;
1069b60736ecSDimitry Andric   if (auto *PGOReader = CGM.getPGOReader()) {
1070461a67faSDimitry Andric     HashVersion = getPGOHashVersion(PGOReader, CGM);
1071b60736ecSDimitry Andric     ProfileVersion = PGOReader->getVersion();
1072b60736ecSDimitry Andric   }
1073461a67faSDimitry Andric 
1074aca2e42cSDimitry Andric   // If MC/DC is enabled, set the MaxConditions to a preset value. Otherwise,
1075aca2e42cSDimitry Andric   // set it to zero. This value impacts the number of conditions accepted in a
1076aca2e42cSDimitry Andric   // given boolean expression, which impacts the size of the bitmap used to
1077aca2e42cSDimitry Andric   // track test vector execution for that boolean expression.  Because the
1078aca2e42cSDimitry Andric   // bitmap scales exponentially (2^n) based on the number of conditions seen,
1079aca2e42cSDimitry Andric   // the maximum value is hard-coded at 6 conditions, which is more than enough
1080aca2e42cSDimitry Andric   // for most embedded applications. Setting a maximum value prevents the
1081aca2e42cSDimitry Andric   // bitmap footprint from growing too large without the user's knowledge. In
1082aca2e42cSDimitry Andric   // the future, this value could be adjusted with a command-line option.
1083ac9a064cSDimitry Andric   unsigned MCDCMaxConditions =
1084ac9a064cSDimitry Andric       (CGM.getCodeGenOpts().MCDCCoverage ? CGM.getCodeGenOpts().MCDCMaxConds
1085ac9a064cSDimitry Andric                                          : 0);
1086aca2e42cSDimitry Andric 
10879f4dbff6SDimitry Andric   RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
1088ac9a064cSDimitry Andric   RegionMCDCState.reset(new MCDC::State);
1089aca2e42cSDimitry Andric   MapRegionCounters Walker(HashVersion, ProfileVersion, *RegionCounterMap,
1090ac9a064cSDimitry Andric                            *RegionMCDCState, MCDCMaxConditions, CGM.getDiags());
10919f4dbff6SDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
10929f4dbff6SDimitry Andric     Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
10939f4dbff6SDimitry Andric   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
10949f4dbff6SDimitry Andric     Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
10959f4dbff6SDimitry Andric   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
10969f4dbff6SDimitry Andric     Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
10979f4dbff6SDimitry Andric   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
10989f4dbff6SDimitry Andric     Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
10999f4dbff6SDimitry Andric   assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
11009f4dbff6SDimitry Andric   NumRegionCounters = Walker.NextCounter;
11019f4dbff6SDimitry Andric   FunctionHash = Walker.Hash.finalize();
11029f4dbff6SDimitry Andric }
11039f4dbff6SDimitry Andric 
skipRegionMappingForDecl(const Decl * D)11042b6b257fSDimitry Andric bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) {
1105f0c55418SDimitry Andric   if (!D->getBody())
11062b6b257fSDimitry Andric     return true;
11072b6b257fSDimitry Andric 
1108b60736ecSDimitry Andric   // Skip host-only functions in the CUDA device compilation and device-only
1109b60736ecSDimitry Andric   // functions in the host compilation. Just roughly filter them out based on
1110b60736ecSDimitry Andric   // the function attributes. If there are effectively host-only or device-only
1111b60736ecSDimitry Andric   // ones, their coverage mapping may still be generated.
1112b60736ecSDimitry Andric   if (CGM.getLangOpts().CUDA &&
1113b60736ecSDimitry Andric       ((CGM.getLangOpts().CUDAIsDevice && !D->hasAttr<CUDADeviceAttr>() &&
1114b60736ecSDimitry Andric         !D->hasAttr<CUDAGlobalAttr>()) ||
1115b60736ecSDimitry Andric        (!CGM.getLangOpts().CUDAIsDevice &&
1116b60736ecSDimitry Andric         (D->hasAttr<CUDAGlobalAttr>() ||
1117b60736ecSDimitry Andric          (!D->hasAttr<CUDAHostAttr>() && D->hasAttr<CUDADeviceAttr>())))))
1118b60736ecSDimitry Andric     return true;
1119b60736ecSDimitry Andric 
11202b6b257fSDimitry Andric   // Don't map the functions in system headers.
11212b6b257fSDimitry Andric   const auto &SM = CGM.getContext().getSourceManager();
1122676fbe81SDimitry Andric   auto Loc = D->getBody()->getBeginLoc();
1123ac9a064cSDimitry Andric   return !llvm::coverage::SystemHeadersCoverage && SM.isInSystemHeader(Loc);
11242b6b257fSDimitry Andric }
11252b6b257fSDimitry Andric 
emitCounterRegionMapping(const Decl * D)11262b6b257fSDimitry Andric void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
11272b6b257fSDimitry Andric   if (skipRegionMappingForDecl(D))
112806d4ba38SDimitry Andric     return;
112906d4ba38SDimitry Andric 
113006d4ba38SDimitry Andric   std::string CoverageMapping;
113106d4ba38SDimitry Andric   llvm::raw_string_ostream OS(CoverageMapping);
1132ac9a064cSDimitry Andric   RegionMCDCState->BranchByStmt.clear();
1133aca2e42cSDimitry Andric   CoverageMappingGen MappingGen(
1134aca2e42cSDimitry Andric       *CGM.getCoverageMapping(), CGM.getContext().getSourceManager(),
1135ac9a064cSDimitry Andric       CGM.getLangOpts(), RegionCounterMap.get(), RegionMCDCState.get());
113606d4ba38SDimitry Andric   MappingGen.emitCounterMapping(D, OS);
113706d4ba38SDimitry Andric   OS.flush();
113806d4ba38SDimitry Andric 
113906d4ba38SDimitry Andric   if (CoverageMapping.empty())
114006d4ba38SDimitry Andric     return;
114106d4ba38SDimitry Andric 
114206d4ba38SDimitry Andric   CGM.getCoverageMapping()->addFunctionMappingRecord(
114306d4ba38SDimitry Andric       FuncNameVar, FuncName, FunctionHash, CoverageMapping);
114406d4ba38SDimitry Andric }
114506d4ba38SDimitry Andric 
114606d4ba38SDimitry Andric void
emitEmptyCounterMapping(const Decl * D,StringRef Name,llvm::GlobalValue::LinkageTypes Linkage)11475e20cdd8SDimitry Andric CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef Name,
114806d4ba38SDimitry Andric                                     llvm::GlobalValue::LinkageTypes Linkage) {
11492b6b257fSDimitry Andric   if (skipRegionMappingForDecl(D))
115006d4ba38SDimitry Andric     return;
115106d4ba38SDimitry Andric 
115206d4ba38SDimitry Andric   std::string CoverageMapping;
115306d4ba38SDimitry Andric   llvm::raw_string_ostream OS(CoverageMapping);
115406d4ba38SDimitry Andric   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
115506d4ba38SDimitry Andric                                 CGM.getContext().getSourceManager(),
115606d4ba38SDimitry Andric                                 CGM.getLangOpts());
115706d4ba38SDimitry Andric   MappingGen.emitEmptyMapping(D, OS);
115806d4ba38SDimitry Andric   OS.flush();
115906d4ba38SDimitry Andric 
116006d4ba38SDimitry Andric   if (CoverageMapping.empty())
116106d4ba38SDimitry Andric     return;
116206d4ba38SDimitry Andric 
11635e20cdd8SDimitry Andric   setFuncName(Name, Linkage);
116406d4ba38SDimitry Andric   CGM.getCoverageMapping()->addFunctionMappingRecord(
11650414e226SDimitry Andric       FuncNameVar, FuncName, FunctionHash, CoverageMapping, false);
116606d4ba38SDimitry Andric }
116706d4ba38SDimitry Andric 
computeRegionCounts(const Decl * D)11689f4dbff6SDimitry Andric void CodeGenPGO::computeRegionCounts(const Decl *D) {
11699f4dbff6SDimitry Andric   StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
11709f4dbff6SDimitry Andric   ComputeRegionCounts Walker(*StmtCountMap, *this);
11719f4dbff6SDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
11729f4dbff6SDimitry Andric     Walker.VisitFunctionDecl(FD);
11739f4dbff6SDimitry Andric   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
11749f4dbff6SDimitry Andric     Walker.VisitObjCMethodDecl(MD);
11759f4dbff6SDimitry Andric   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
11769f4dbff6SDimitry Andric     Walker.VisitBlockDecl(BD);
11779f4dbff6SDimitry Andric   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
11789f4dbff6SDimitry Andric     Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
11799f4dbff6SDimitry Andric }
11809f4dbff6SDimitry Andric 
11819f4dbff6SDimitry Andric void
applyFunctionAttributes(llvm::IndexedInstrProfReader * PGOReader,llvm::Function * Fn)11829f4dbff6SDimitry Andric CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
11839f4dbff6SDimitry Andric                                     llvm::Function *Fn) {
11849f4dbff6SDimitry Andric   if (!haveRegionCounts())
11859f4dbff6SDimitry Andric     return;
11869f4dbff6SDimitry Andric 
118745b53394SDimitry Andric   uint64_t FunctionCount = getRegionCount(nullptr);
1188798321d8SDimitry Andric   Fn->setEntryCount(FunctionCount);
11899f4dbff6SDimitry Andric }
11909f4dbff6SDimitry Andric 
emitCounterSetOrIncrement(CGBuilderTy & Builder,const Stmt * S,llvm::Value * StepV)1191ac9a064cSDimitry Andric void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S,
11927442d6faSDimitry Andric                                            llvm::Value *StepV) {
1193b1c73532SDimitry Andric   if (!RegionCounterMap || !Builder.GetInsertBlock())
119406d4ba38SDimitry Andric     return;
11955e20cdd8SDimitry Andric 
11965e20cdd8SDimitry Andric   unsigned Counter = (*RegionCounterMap)[S];
11977442d6faSDimitry Andric 
1198b1c73532SDimitry Andric   llvm::Value *Args[] = {FuncNameVar,
119906d4ba38SDimitry Andric                          Builder.getInt64(FunctionHash),
120006d4ba38SDimitry Andric                          Builder.getInt32(NumRegionCounters),
12017442d6faSDimitry Andric                          Builder.getInt32(Counter), StepV};
1202ac9a064cSDimitry Andric 
1203ac9a064cSDimitry Andric   if (llvm::EnableSingleByteCoverage)
1204ac9a064cSDimitry Andric     Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_cover),
1205ac9a064cSDimitry Andric                        ArrayRef(Args, 4));
1206ac9a064cSDimitry Andric   else {
12077442d6faSDimitry Andric     if (!StepV)
12087442d6faSDimitry Andric       Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
1209e3b55780SDimitry Andric                          ArrayRef(Args, 4));
12107442d6faSDimitry Andric     else
12117442d6faSDimitry Andric       Builder.CreateCall(
1212ac9a064cSDimitry Andric           CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment_step), Args);
1213ac9a064cSDimitry Andric   }
12149f4dbff6SDimitry Andric }
12159f4dbff6SDimitry Andric 
canEmitMCDCCoverage(const CGBuilderTy & Builder)1216aca2e42cSDimitry Andric bool CodeGenPGO::canEmitMCDCCoverage(const CGBuilderTy &Builder) {
1217aca2e42cSDimitry Andric   return (CGM.getCodeGenOpts().hasProfileClangInstr() &&
1218aca2e42cSDimitry Andric           CGM.getCodeGenOpts().MCDCCoverage && Builder.GetInsertBlock());
1219aca2e42cSDimitry Andric }
1220aca2e42cSDimitry Andric 
emitMCDCParameters(CGBuilderTy & Builder)1221aca2e42cSDimitry Andric void CodeGenPGO::emitMCDCParameters(CGBuilderTy &Builder) {
1222ac9a064cSDimitry Andric   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
1223aca2e42cSDimitry Andric     return;
1224aca2e42cSDimitry Andric 
1225aca2e42cSDimitry Andric   auto *I8PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
1226aca2e42cSDimitry Andric 
1227aca2e42cSDimitry Andric   // Emit intrinsic representing MCDC bitmap parameters at function entry.
1228aca2e42cSDimitry Andric   // This is used by the instrumentation pass, but it isn't actually lowered to
1229aca2e42cSDimitry Andric   // anything.
1230aca2e42cSDimitry Andric   llvm::Value *Args[3] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
1231aca2e42cSDimitry Andric                           Builder.getInt64(FunctionHash),
1232ac9a064cSDimitry Andric                           Builder.getInt32(RegionMCDCState->BitmapBits)};
1233aca2e42cSDimitry Andric   Builder.CreateCall(
1234aca2e42cSDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_parameters), Args);
1235aca2e42cSDimitry Andric }
1236aca2e42cSDimitry Andric 
emitMCDCTestVectorBitmapUpdate(CGBuilderTy & Builder,const Expr * S,Address MCDCCondBitmapAddr,CodeGenFunction & CGF)1237aca2e42cSDimitry Andric void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
1238aca2e42cSDimitry Andric                                                 const Expr *S,
1239ac9a064cSDimitry Andric                                                 Address MCDCCondBitmapAddr,
1240ac9a064cSDimitry Andric                                                 CodeGenFunction &CGF) {
1241ac9a064cSDimitry Andric   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
1242aca2e42cSDimitry Andric     return;
1243aca2e42cSDimitry Andric 
1244aca2e42cSDimitry Andric   S = S->IgnoreParens();
1245aca2e42cSDimitry Andric 
1246ac9a064cSDimitry Andric   auto DecisionStateIter = RegionMCDCState->DecisionByStmt.find(S);
1247ac9a064cSDimitry Andric   if (DecisionStateIter == RegionMCDCState->DecisionByStmt.end())
1248aca2e42cSDimitry Andric     return;
1249aca2e42cSDimitry Andric 
1250ac9a064cSDimitry Andric   // Don't create tvbitmap_update if the record is allocated but excluded.
1251ac9a064cSDimitry Andric   // Or `bitmap |= (1 << 0)` would be wrongly executed to the next bitmap.
1252ac9a064cSDimitry Andric   if (DecisionStateIter->second.Indices.size() == 0)
1253ac9a064cSDimitry Andric     return;
1254ac9a064cSDimitry Andric 
1255ac9a064cSDimitry Andric   // Extract the offset of the global bitmap associated with this expression.
1256ac9a064cSDimitry Andric   unsigned MCDCTestVectorBitmapOffset = DecisionStateIter->second.BitmapIdx;
1257aca2e42cSDimitry Andric   auto *I8PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
1258aca2e42cSDimitry Andric 
1259aca2e42cSDimitry Andric   // Emit intrinsic responsible for updating the global bitmap corresponding to
1260aca2e42cSDimitry Andric   // a boolean expression. The index being set is based on the value loaded
1261aca2e42cSDimitry Andric   // from a pointer to a dedicated temporary value on the stack that is itself
1262aca2e42cSDimitry Andric   // updated via emitMCDCCondBitmapReset() and emitMCDCCondBitmapUpdate(). The
1263aca2e42cSDimitry Andric   // index represents an executed test vector.
1264ac9a064cSDimitry Andric   llvm::Value *Args[4] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
1265aca2e42cSDimitry Andric                           Builder.getInt64(FunctionHash),
1266ac9a064cSDimitry Andric                           Builder.getInt32(MCDCTestVectorBitmapOffset),
1267ac9a064cSDimitry Andric                           MCDCCondBitmapAddr.emitRawPointer(CGF)};
1268aca2e42cSDimitry Andric   Builder.CreateCall(
1269aca2e42cSDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_tvbitmap_update), Args);
1270aca2e42cSDimitry Andric }
1271aca2e42cSDimitry Andric 
emitMCDCCondBitmapReset(CGBuilderTy & Builder,const Expr * S,Address MCDCCondBitmapAddr)1272aca2e42cSDimitry Andric void CodeGenPGO::emitMCDCCondBitmapReset(CGBuilderTy &Builder, const Expr *S,
1273aca2e42cSDimitry Andric                                          Address MCDCCondBitmapAddr) {
1274ac9a064cSDimitry Andric   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
1275aca2e42cSDimitry Andric     return;
1276aca2e42cSDimitry Andric 
1277aca2e42cSDimitry Andric   S = S->IgnoreParens();
1278aca2e42cSDimitry Andric 
1279ac9a064cSDimitry Andric   if (!RegionMCDCState->DecisionByStmt.contains(S))
1280aca2e42cSDimitry Andric     return;
1281aca2e42cSDimitry Andric 
1282aca2e42cSDimitry Andric   // Emit intrinsic that resets a dedicated temporary value on the stack to 0.
1283aca2e42cSDimitry Andric   Builder.CreateStore(Builder.getInt32(0), MCDCCondBitmapAddr);
1284aca2e42cSDimitry Andric }
1285aca2e42cSDimitry Andric 
emitMCDCCondBitmapUpdate(CGBuilderTy & Builder,const Expr * S,Address MCDCCondBitmapAddr,llvm::Value * Val,CodeGenFunction & CGF)1286aca2e42cSDimitry Andric void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S,
1287aca2e42cSDimitry Andric                                           Address MCDCCondBitmapAddr,
1288ac9a064cSDimitry Andric                                           llvm::Value *Val,
1289ac9a064cSDimitry Andric                                           CodeGenFunction &CGF) {
1290ac9a064cSDimitry Andric   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
1291aca2e42cSDimitry Andric     return;
1292aca2e42cSDimitry Andric 
1293aca2e42cSDimitry Andric   // Even though, for simplicity, parentheses and unary logical-NOT operators
1294aca2e42cSDimitry Andric   // are considered part of their underlying condition for both MC/DC and
1295aca2e42cSDimitry Andric   // branch coverage, the condition IDs themselves are assigned and tracked
1296aca2e42cSDimitry Andric   // using the underlying condition itself.  This is done solely for
1297aca2e42cSDimitry Andric   // consistency since parentheses and logical-NOTs are ignored when checking
1298aca2e42cSDimitry Andric   // whether the condition is actually an instrumentable condition. This can
1299aca2e42cSDimitry Andric   // also make debugging a bit easier.
1300aca2e42cSDimitry Andric   S = CodeGenFunction::stripCond(S);
1301aca2e42cSDimitry Andric 
1302ac9a064cSDimitry Andric   auto BranchStateIter = RegionMCDCState->BranchByStmt.find(S);
1303ac9a064cSDimitry Andric   if (BranchStateIter == RegionMCDCState->BranchByStmt.end())
1304aca2e42cSDimitry Andric     return;
1305aca2e42cSDimitry Andric 
1306aca2e42cSDimitry Andric   // Extract the ID of the condition we are setting in the bitmap.
1307ac9a064cSDimitry Andric   const auto &Branch = BranchStateIter->second;
1308ac9a064cSDimitry Andric   assert(Branch.ID >= 0 && "Condition has no ID!");
1309ac9a064cSDimitry Andric   assert(Branch.DecisionStmt);
1310aca2e42cSDimitry Andric 
1311ac9a064cSDimitry Andric   // Cancel the emission if the Decision is erased after the allocation.
1312ac9a064cSDimitry Andric   const auto DecisionIter =
1313ac9a064cSDimitry Andric       RegionMCDCState->DecisionByStmt.find(Branch.DecisionStmt);
1314ac9a064cSDimitry Andric   if (DecisionIter == RegionMCDCState->DecisionByStmt.end())
1315ac9a064cSDimitry Andric     return;
1316aca2e42cSDimitry Andric 
1317ac9a064cSDimitry Andric   const auto &TVIdxs = DecisionIter->second.Indices[Branch.ID];
1318ac9a064cSDimitry Andric 
1319ac9a064cSDimitry Andric   auto *CurTV = Builder.CreateLoad(MCDCCondBitmapAddr,
1320ac9a064cSDimitry Andric                                    "mcdc." + Twine(Branch.ID + 1) + ".cur");
1321ac9a064cSDimitry Andric   auto *NewTV = Builder.CreateAdd(CurTV, Builder.getInt32(TVIdxs[true]));
1322ac9a064cSDimitry Andric   NewTV = Builder.CreateSelect(
1323ac9a064cSDimitry Andric       Val, NewTV, Builder.CreateAdd(CurTV, Builder.getInt32(TVIdxs[false])));
1324ac9a064cSDimitry Andric   Builder.CreateStore(NewTV, MCDCCondBitmapAddr);
1325aca2e42cSDimitry Andric }
1326aca2e42cSDimitry Andric 
setValueProfilingFlag(llvm::Module & M)1327344a3780SDimitry Andric void CodeGenPGO::setValueProfilingFlag(llvm::Module &M) {
1328344a3780SDimitry Andric   if (CGM.getCodeGenOpts().hasProfileClangInstr())
1329344a3780SDimitry Andric     M.addModuleFlag(llvm::Module::Warning, "EnableValueProfiling",
1330344a3780SDimitry Andric                     uint32_t(EnableValueProfiling));
1331344a3780SDimitry Andric }
1332344a3780SDimitry Andric 
setProfileVersion(llvm::Module & M)1333ac9a064cSDimitry Andric void CodeGenPGO::setProfileVersion(llvm::Module &M) {
1334ac9a064cSDimitry Andric   if (CGM.getCodeGenOpts().hasProfileClangInstr() &&
1335ac9a064cSDimitry Andric       llvm::EnableSingleByteCoverage) {
1336ac9a064cSDimitry Andric     const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
1337ac9a064cSDimitry Andric     llvm::Type *IntTy64 = llvm::Type::getInt64Ty(M.getContext());
1338ac9a064cSDimitry Andric     uint64_t ProfileVersion =
1339ac9a064cSDimitry Andric         (INSTR_PROF_RAW_VERSION | VARIANT_MASK_BYTE_COVERAGE);
1340ac9a064cSDimitry Andric 
1341ac9a064cSDimitry Andric     auto IRLevelVersionVariable = new llvm::GlobalVariable(
1342ac9a064cSDimitry Andric         M, IntTy64, true, llvm::GlobalValue::WeakAnyLinkage,
1343ac9a064cSDimitry Andric         llvm::Constant::getIntegerValue(IntTy64,
1344ac9a064cSDimitry Andric                                         llvm::APInt(64, ProfileVersion)),
1345ac9a064cSDimitry Andric         VarName);
1346ac9a064cSDimitry Andric 
1347ac9a064cSDimitry Andric     IRLevelVersionVariable->setVisibility(llvm::GlobalValue::HiddenVisibility);
1348ac9a064cSDimitry Andric     llvm::Triple TT(M.getTargetTriple());
1349ac9a064cSDimitry Andric     if (TT.supportsCOMDAT()) {
1350ac9a064cSDimitry Andric       IRLevelVersionVariable->setLinkage(llvm::GlobalValue::ExternalLinkage);
1351ac9a064cSDimitry Andric       IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName));
1352ac9a064cSDimitry Andric     }
1353ac9a064cSDimitry Andric     IRLevelVersionVariable->setDSOLocal(true);
1354ac9a064cSDimitry Andric   }
1355ac9a064cSDimitry Andric }
1356ac9a064cSDimitry Andric 
13572b6b257fSDimitry Andric // This method either inserts a call to the profile run-time during
13582b6b257fSDimitry Andric // instrumentation or puts profile data into metadata for PGO use.
valueProfile(CGBuilderTy & Builder,uint32_t ValueKind,llvm::Instruction * ValueSite,llvm::Value * ValuePtr)13592b6b257fSDimitry Andric void CodeGenPGO::valueProfile(CGBuilderTy &Builder, uint32_t ValueKind,
13602b6b257fSDimitry Andric     llvm::Instruction *ValueSite, llvm::Value *ValuePtr) {
13612b6b257fSDimitry Andric 
13622b6b257fSDimitry Andric   if (!EnableValueProfiling)
13632b6b257fSDimitry Andric     return;
13642b6b257fSDimitry Andric 
13652b6b257fSDimitry Andric   if (!ValuePtr || !ValueSite || !Builder.GetInsertBlock())
13662b6b257fSDimitry Andric     return;
13672b6b257fSDimitry Andric 
13682b6b257fSDimitry Andric   if (isa<llvm::Constant>(ValuePtr))
13692b6b257fSDimitry Andric     return;
13702b6b257fSDimitry Andric 
13712b6b257fSDimitry Andric   bool InstrumentValueSites = CGM.getCodeGenOpts().hasProfileClangInstr();
13722b6b257fSDimitry Andric   if (InstrumentValueSites && RegionCounterMap) {
13732b6b257fSDimitry Andric     auto BuilderInsertPoint = Builder.saveIP();
13742b6b257fSDimitry Andric     Builder.SetInsertPoint(ValueSite);
13752b6b257fSDimitry Andric     llvm::Value *Args[5] = {
1376b1c73532SDimitry Andric         FuncNameVar,
13772b6b257fSDimitry Andric         Builder.getInt64(FunctionHash),
13782b6b257fSDimitry Andric         Builder.CreatePtrToInt(ValuePtr, Builder.getInt64Ty()),
13792b6b257fSDimitry Andric         Builder.getInt32(ValueKind),
13802b6b257fSDimitry Andric         Builder.getInt32(NumValueSites[ValueKind]++)
13812b6b257fSDimitry Andric     };
13822b6b257fSDimitry Andric     Builder.CreateCall(
13832b6b257fSDimitry Andric         CGM.getIntrinsic(llvm::Intrinsic::instrprof_value_profile), Args);
13842b6b257fSDimitry Andric     Builder.restoreIP(BuilderInsertPoint);
13852b6b257fSDimitry Andric     return;
13862b6b257fSDimitry Andric   }
13872b6b257fSDimitry Andric 
13882b6b257fSDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
13892b6b257fSDimitry Andric   if (PGOReader && haveRegionCounts()) {
13902b6b257fSDimitry Andric     // We record the top most called three functions at each call site.
13912b6b257fSDimitry Andric     // Profile metadata contains "VP" string identifying this metadata
13922b6b257fSDimitry Andric     // as value profiling data, then a uint32_t value for the value profiling
13932b6b257fSDimitry Andric     // kind, a uint64_t value for the total number of times the call is
13942b6b257fSDimitry Andric     // executed, followed by the function hash and execution count (uint64_t)
13952b6b257fSDimitry Andric     // pairs for each function.
13962b6b257fSDimitry Andric     if (NumValueSites[ValueKind] >= ProfRecord->getNumValueSites(ValueKind))
13972b6b257fSDimitry Andric       return;
13982b6b257fSDimitry Andric 
13992b6b257fSDimitry Andric     llvm::annotateValueSite(CGM.getModule(), *ValueSite, *ProfRecord,
14002b6b257fSDimitry Andric                             (llvm::InstrProfValueKind)ValueKind,
14012b6b257fSDimitry Andric                             NumValueSites[ValueKind]);
14022b6b257fSDimitry Andric 
14032b6b257fSDimitry Andric     NumValueSites[ValueKind]++;
14042b6b257fSDimitry Andric   }
14052b6b257fSDimitry Andric }
14062b6b257fSDimitry Andric 
loadRegionCounts(llvm::IndexedInstrProfReader * PGOReader,bool IsInMainFile)14079f4dbff6SDimitry Andric void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
14089f4dbff6SDimitry Andric                                   bool IsInMainFile) {
14099f4dbff6SDimitry Andric   CGM.getPGOStats().addVisited(IsInMainFile);
141006d4ba38SDimitry Andric   RegionCounts.clear();
14112b6b257fSDimitry Andric   llvm::Expected<llvm::InstrProfRecord> RecordExpected =
14122b6b257fSDimitry Andric       PGOReader->getInstrProfRecord(FuncName, FunctionHash);
14132b6b257fSDimitry Andric   if (auto E = RecordExpected.takeError()) {
14147fa27ce4SDimitry Andric     auto IPE = std::get<0>(llvm::InstrProfError::take(std::move(E)));
14152b6b257fSDimitry Andric     if (IPE == llvm::instrprof_error::unknown_function)
14169f4dbff6SDimitry Andric       CGM.getPGOStats().addMissing(IsInMainFile);
14172b6b257fSDimitry Andric     else if (IPE == llvm::instrprof_error::hash_mismatch)
14189f4dbff6SDimitry Andric       CGM.getPGOStats().addMismatched(IsInMainFile);
14192b6b257fSDimitry Andric     else if (IPE == llvm::instrprof_error::malformed)
142006d4ba38SDimitry Andric       // TODO: Consider a more specific warning for this case.
142106d4ba38SDimitry Andric       CGM.getPGOStats().addMismatched(IsInMainFile);
14222b6b257fSDimitry Andric     return;
14239f4dbff6SDimitry Andric   }
14242b6b257fSDimitry Andric   ProfRecord =
1425519fc96cSDimitry Andric       std::make_unique<llvm::InstrProfRecord>(std::move(RecordExpected.get()));
14262b6b257fSDimitry Andric   RegionCounts = ProfRecord->Counts;
14279f4dbff6SDimitry Andric }
14289f4dbff6SDimitry Andric 
142948675466SDimitry Andric /// Calculate what to divide by to scale weights.
14309f4dbff6SDimitry Andric ///
14319f4dbff6SDimitry Andric /// Given the maximum weight, calculate a divisor that will scale all the
14329f4dbff6SDimitry Andric /// weights to strictly less than UINT32_MAX.
calculateWeightScale(uint64_t MaxWeight)14339f4dbff6SDimitry Andric static uint64_t calculateWeightScale(uint64_t MaxWeight) {
14349f4dbff6SDimitry Andric   return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
14359f4dbff6SDimitry Andric }
14369f4dbff6SDimitry Andric 
143748675466SDimitry Andric /// Scale an individual branch weight (and add 1).
14389f4dbff6SDimitry Andric ///
14399f4dbff6SDimitry Andric /// Scale a 64-bit weight down to 32-bits using \c Scale.
14409f4dbff6SDimitry Andric ///
14419f4dbff6SDimitry Andric /// According to Laplace's Rule of Succession, it is better to compute the
14429f4dbff6SDimitry Andric /// weight based on the count plus 1, so universally add 1 to the value.
14439f4dbff6SDimitry Andric ///
14449f4dbff6SDimitry Andric /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
14459f4dbff6SDimitry Andric /// greater than \c Weight.
scaleBranchWeight(uint64_t Weight,uint64_t Scale)14469f4dbff6SDimitry Andric static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
14479f4dbff6SDimitry Andric   assert(Scale && "scale by 0?");
14489f4dbff6SDimitry Andric   uint64_t Scaled = Weight / Scale + 1;
14499f4dbff6SDimitry Andric   assert(Scaled <= UINT32_MAX && "overflow 32-bits");
14509f4dbff6SDimitry Andric   return Scaled;
14519f4dbff6SDimitry Andric }
14529f4dbff6SDimitry Andric 
createProfileWeights(uint64_t TrueCount,uint64_t FalseCount) const14535e20cdd8SDimitry Andric llvm::MDNode *CodeGenFunction::createProfileWeights(uint64_t TrueCount,
1454b60736ecSDimitry Andric                                                     uint64_t FalseCount) const {
14559f4dbff6SDimitry Andric   // Check for empty weights.
14569f4dbff6SDimitry Andric   if (!TrueCount && !FalseCount)
14579f4dbff6SDimitry Andric     return nullptr;
14589f4dbff6SDimitry Andric 
14599f4dbff6SDimitry Andric   // Calculate how to scale down to 32-bits.
14609f4dbff6SDimitry Andric   uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
14619f4dbff6SDimitry Andric 
14629f4dbff6SDimitry Andric   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
14639f4dbff6SDimitry Andric   return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
14649f4dbff6SDimitry Andric                                       scaleBranchWeight(FalseCount, Scale));
14659f4dbff6SDimitry Andric }
14669f4dbff6SDimitry Andric 
14675e20cdd8SDimitry Andric llvm::MDNode *
createProfileWeights(ArrayRef<uint64_t> Weights) const1468b60736ecSDimitry Andric CodeGenFunction::createProfileWeights(ArrayRef<uint64_t> Weights) const {
14699f4dbff6SDimitry Andric   // We need at least two elements to create meaningful weights.
14709f4dbff6SDimitry Andric   if (Weights.size() < 2)
14719f4dbff6SDimitry Andric     return nullptr;
14729f4dbff6SDimitry Andric 
14739f4dbff6SDimitry Andric   // Check for empty weights.
14749f4dbff6SDimitry Andric   uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
14759f4dbff6SDimitry Andric   if (MaxWeight == 0)
14769f4dbff6SDimitry Andric     return nullptr;
14779f4dbff6SDimitry Andric 
14789f4dbff6SDimitry Andric   // Calculate how to scale down to 32-bits.
14799f4dbff6SDimitry Andric   uint64_t Scale = calculateWeightScale(MaxWeight);
14809f4dbff6SDimitry Andric 
14819f4dbff6SDimitry Andric   SmallVector<uint32_t, 16> ScaledWeights;
14829f4dbff6SDimitry Andric   ScaledWeights.reserve(Weights.size());
14839f4dbff6SDimitry Andric   for (uint64_t W : Weights)
14849f4dbff6SDimitry Andric     ScaledWeights.push_back(scaleBranchWeight(W, Scale));
14859f4dbff6SDimitry Andric 
14869f4dbff6SDimitry Andric   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
14879f4dbff6SDimitry Andric   return MDHelper.createBranchWeights(ScaledWeights);
14889f4dbff6SDimitry Andric }
14899f4dbff6SDimitry Andric 
1490b60736ecSDimitry Andric llvm::MDNode *
createProfileWeightsForLoop(const Stmt * Cond,uint64_t LoopCount) const1491b60736ecSDimitry Andric CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond,
1492b60736ecSDimitry Andric                                              uint64_t LoopCount) const {
14935e20cdd8SDimitry Andric   if (!PGO.haveRegionCounts())
14949f4dbff6SDimitry Andric     return nullptr;
1495e3b55780SDimitry Andric   std::optional<uint64_t> CondCount = PGO.getStmtCount(Cond);
1496cfca06d7SDimitry Andric   if (!CondCount || *CondCount == 0)
14979f4dbff6SDimitry Andric     return nullptr;
14985e20cdd8SDimitry Andric   return createProfileWeights(LoopCount,
14995e20cdd8SDimitry Andric                               std::max(*CondCount, LoopCount) - LoopCount);
15009f4dbff6SDimitry Andric }
1501