10b57cec5SDimitry Andric //===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Instrumentation-based profile-guided optimization
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "CodeGenPGO.h"
140b57cec5SDimitry Andric #include "CodeGenFunction.h"
150b57cec5SDimitry Andric #include "CoverageMappingGen.h"
160b57cec5SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
170b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h"
180b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
190b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h"
20480093f4SDimitry Andric #include "llvm/Support/CommandLine.h"
210b57cec5SDimitry Andric #include "llvm/Support/Endian.h"
220b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
230b57cec5SDimitry Andric #include "llvm/Support/MD5.h"
24bdd1243dSDimitry Andric #include <optional>
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric static llvm::cl::opt<bool>
2781ad6265SDimitry Andric     EnableValueProfiling("enable-value-profiling",
280b57cec5SDimitry Andric                          llvm::cl::desc("Enable value profiling"),
290b57cec5SDimitry Andric                          llvm::cl::Hidden, llvm::cl::init(false));
300b57cec5SDimitry Andric 
31a58f00eaSDimitry Andric extern llvm::cl::opt<bool> SystemHeadersCoverage;
32a58f00eaSDimitry Andric 
330b57cec5SDimitry Andric using namespace clang;
340b57cec5SDimitry Andric using namespace CodeGen;
350b57cec5SDimitry Andric 
setFuncName(StringRef Name,llvm::GlobalValue::LinkageTypes Linkage)360b57cec5SDimitry Andric void CodeGenPGO::setFuncName(StringRef Name,
370b57cec5SDimitry Andric                              llvm::GlobalValue::LinkageTypes Linkage) {
380b57cec5SDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
390b57cec5SDimitry Andric   FuncName = llvm::getPGOFuncName(
400b57cec5SDimitry Andric       Name, Linkage, CGM.getCodeGenOpts().MainFileName,
410b57cec5SDimitry Andric       PGOReader ? PGOReader->getVersion() : llvm::IndexedInstrProf::Version);
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric   // If we're generating a profile, create a variable for the name.
440b57cec5SDimitry Andric   if (CGM.getCodeGenOpts().hasProfileClangInstr())
450b57cec5SDimitry Andric     FuncNameVar = llvm::createPGOFuncNameVar(CGM.getModule(), Linkage, FuncName);
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric 
setFuncName(llvm::Function * Fn)480b57cec5SDimitry Andric void CodeGenPGO::setFuncName(llvm::Function *Fn) {
490b57cec5SDimitry Andric   setFuncName(Fn->getName(), Fn->getLinkage());
500b57cec5SDimitry Andric   // Create PGOFuncName meta data.
510b57cec5SDimitry Andric   llvm::createPGOFuncNameMetadata(*Fn, FuncName);
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric /// The version of the PGO hash algorithm.
550b57cec5SDimitry Andric enum PGOHashVersion : unsigned {
560b57cec5SDimitry Andric   PGO_HASH_V1,
570b57cec5SDimitry Andric   PGO_HASH_V2,
585ffd83dbSDimitry Andric   PGO_HASH_V3,
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   // Keep this set to the latest hash version.
615ffd83dbSDimitry Andric   PGO_HASH_LATEST = PGO_HASH_V3
620b57cec5SDimitry Andric };
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric namespace {
650b57cec5SDimitry Andric /// Stable hasher for PGO region counters.
660b57cec5SDimitry Andric ///
670b57cec5SDimitry Andric /// PGOHash produces a stable hash of a given function's control flow.
680b57cec5SDimitry Andric ///
690b57cec5SDimitry Andric /// Changing the output of this hash will invalidate all previously generated
700b57cec5SDimitry Andric /// profiles -- i.e., don't do it.
710b57cec5SDimitry Andric ///
720b57cec5SDimitry Andric /// \note  When this hash does eventually change (years?), we still need to
730b57cec5SDimitry Andric /// support old hashes.  We'll need to pull in the version number from the
740b57cec5SDimitry Andric /// profile data format and use the matching hash function.
750b57cec5SDimitry Andric class PGOHash {
760b57cec5SDimitry Andric   uint64_t Working;
770b57cec5SDimitry Andric   unsigned Count;
780b57cec5SDimitry Andric   PGOHashVersion HashVersion;
790b57cec5SDimitry Andric   llvm::MD5 MD5;
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   static const int NumBitsPerType = 6;
820b57cec5SDimitry Andric   static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
830b57cec5SDimitry Andric   static const unsigned TooBig = 1u << NumBitsPerType;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric public:
860b57cec5SDimitry Andric   /// Hash values for AST nodes.
870b57cec5SDimitry Andric   ///
880b57cec5SDimitry Andric   /// Distinct values for AST nodes that have region counters attached.
890b57cec5SDimitry Andric   ///
900b57cec5SDimitry Andric   /// These values must be stable.  All new members must be added at the end,
910b57cec5SDimitry Andric   /// and no members should be removed.  Changing the enumeration value for an
920b57cec5SDimitry Andric   /// AST node will affect the hash of every function that contains that node.
930b57cec5SDimitry Andric   enum HashType : unsigned char {
940b57cec5SDimitry Andric     None = 0,
950b57cec5SDimitry Andric     LabelStmt = 1,
960b57cec5SDimitry Andric     WhileStmt,
970b57cec5SDimitry Andric     DoStmt,
980b57cec5SDimitry Andric     ForStmt,
990b57cec5SDimitry Andric     CXXForRangeStmt,
1000b57cec5SDimitry Andric     ObjCForCollectionStmt,
1010b57cec5SDimitry Andric     SwitchStmt,
1020b57cec5SDimitry Andric     CaseStmt,
1030b57cec5SDimitry Andric     DefaultStmt,
1040b57cec5SDimitry Andric     IfStmt,
1050b57cec5SDimitry Andric     CXXTryStmt,
1060b57cec5SDimitry Andric     CXXCatchStmt,
1070b57cec5SDimitry Andric     ConditionalOperator,
1080b57cec5SDimitry Andric     BinaryOperatorLAnd,
1090b57cec5SDimitry Andric     BinaryOperatorLOr,
1100b57cec5SDimitry Andric     BinaryConditionalOperator,
1110b57cec5SDimitry Andric     // The preceding values are available with PGO_HASH_V1.
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric     EndOfScope,
1140b57cec5SDimitry Andric     IfThenBranch,
1150b57cec5SDimitry Andric     IfElseBranch,
1160b57cec5SDimitry Andric     GotoStmt,
1170b57cec5SDimitry Andric     IndirectGotoStmt,
1180b57cec5SDimitry Andric     BreakStmt,
1190b57cec5SDimitry Andric     ContinueStmt,
1200b57cec5SDimitry Andric     ReturnStmt,
1210b57cec5SDimitry Andric     ThrowExpr,
1220b57cec5SDimitry Andric     UnaryOperatorLNot,
1230b57cec5SDimitry Andric     BinaryOperatorLT,
1240b57cec5SDimitry Andric     BinaryOperatorGT,
1250b57cec5SDimitry Andric     BinaryOperatorLE,
1260b57cec5SDimitry Andric     BinaryOperatorGE,
1270b57cec5SDimitry Andric     BinaryOperatorEQ,
1280b57cec5SDimitry Andric     BinaryOperatorNE,
1295ffd83dbSDimitry Andric     // The preceding values are available since PGO_HASH_V2.
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric     // Keep this last.  It's for the static assert that follows.
1320b57cec5SDimitry Andric     LastHashType
1330b57cec5SDimitry Andric   };
1340b57cec5SDimitry Andric   static_assert(LastHashType <= TooBig, "Too many types in HashType");
1350b57cec5SDimitry Andric 
PGOHash(PGOHashVersion HashVersion)1360b57cec5SDimitry Andric   PGOHash(PGOHashVersion HashVersion)
13704eeddc0SDimitry Andric       : Working(0), Count(0), HashVersion(HashVersion) {}
1380b57cec5SDimitry Andric   void combine(HashType Type);
1390b57cec5SDimitry Andric   uint64_t finalize();
getHashVersion() const1400b57cec5SDimitry Andric   PGOHashVersion getHashVersion() const { return HashVersion; }
1410b57cec5SDimitry Andric };
1420b57cec5SDimitry Andric const int PGOHash::NumBitsPerType;
1430b57cec5SDimitry Andric const unsigned PGOHash::NumTypesPerWord;
1440b57cec5SDimitry Andric const unsigned PGOHash::TooBig;
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric /// Get the PGO hash version used in the given indexed profile.
getPGOHashVersion(llvm::IndexedInstrProfReader * PGOReader,CodeGenModule & CGM)1470b57cec5SDimitry Andric static PGOHashVersion getPGOHashVersion(llvm::IndexedInstrProfReader *PGOReader,
1480b57cec5SDimitry Andric                                         CodeGenModule &CGM) {
1490b57cec5SDimitry Andric   if (PGOReader->getVersion() <= 4)
1500b57cec5SDimitry Andric     return PGO_HASH_V1;
1515ffd83dbSDimitry Andric   if (PGOReader->getVersion() <= 5)
1520b57cec5SDimitry Andric     return PGO_HASH_V2;
1535ffd83dbSDimitry Andric   return PGO_HASH_V3;
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
1570b57cec5SDimitry Andric struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
1580b57cec5SDimitry Andric   using Base = RecursiveASTVisitor<MapRegionCounters>;
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   /// The next counter value to assign.
1610b57cec5SDimitry Andric   unsigned NextCounter;
1620b57cec5SDimitry Andric   /// The function hash.
1630b57cec5SDimitry Andric   PGOHash Hash;
1640b57cec5SDimitry Andric   /// The map of statements to counters.
1650b57cec5SDimitry Andric   llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
166cdc20ff6SDimitry Andric   /// The next bitmap byte index to assign.
167cdc20ff6SDimitry Andric   unsigned NextMCDCBitmapIdx;
168cdc20ff6SDimitry Andric   /// The map of statements to MC/DC bitmap coverage objects.
169cdc20ff6SDimitry Andric   llvm::DenseMap<const Stmt *, unsigned> &MCDCBitmapMap;
170cdc20ff6SDimitry Andric   /// Maximum number of supported MC/DC conditions in a boolean expression.
171cdc20ff6SDimitry Andric   unsigned MCDCMaxCond;
172e8d8bef9SDimitry Andric   /// The profile version.
173e8d8bef9SDimitry Andric   uint64_t ProfileVersion;
174cdc20ff6SDimitry Andric   /// Diagnostics Engine used to report warnings.
175cdc20ff6SDimitry Andric   DiagnosticsEngine &Diag;
1760b57cec5SDimitry Andric 
MapRegionCounters__anonfabf342f0111::MapRegionCounters177e8d8bef9SDimitry Andric   MapRegionCounters(PGOHashVersion HashVersion, uint64_t ProfileVersion,
178cdc20ff6SDimitry Andric                     llvm::DenseMap<const Stmt *, unsigned> &CounterMap,
179cdc20ff6SDimitry Andric                     llvm::DenseMap<const Stmt *, unsigned> &MCDCBitmapMap,
180cdc20ff6SDimitry Andric                     unsigned MCDCMaxCond, DiagnosticsEngine &Diag)
181e8d8bef9SDimitry Andric       : NextCounter(0), Hash(HashVersion), CounterMap(CounterMap),
182cdc20ff6SDimitry Andric         NextMCDCBitmapIdx(0), MCDCBitmapMap(MCDCBitmapMap),
183cdc20ff6SDimitry Andric         MCDCMaxCond(MCDCMaxCond), ProfileVersion(ProfileVersion), Diag(Diag) {}
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   // Blocks and lambdas are handled as separate functions, so we need not
1860b57cec5SDimitry Andric   // traverse them in the parent context.
TraverseBlockExpr__anonfabf342f0111::MapRegionCounters1870b57cec5SDimitry Andric   bool TraverseBlockExpr(BlockExpr *BE) { return true; }
TraverseLambdaExpr__anonfabf342f0111::MapRegionCounters1880b57cec5SDimitry Andric   bool TraverseLambdaExpr(LambdaExpr *LE) {
1890b57cec5SDimitry Andric     // Traverse the captures, but not the body.
190480093f4SDimitry Andric     for (auto C : zip(LE->captures(), LE->capture_inits()))
1910b57cec5SDimitry Andric       TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
1920b57cec5SDimitry Andric     return true;
1930b57cec5SDimitry Andric   }
TraverseCapturedStmt__anonfabf342f0111::MapRegionCounters1940b57cec5SDimitry Andric   bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
1950b57cec5SDimitry Andric 
VisitDecl__anonfabf342f0111::MapRegionCounters1960b57cec5SDimitry Andric   bool VisitDecl(const Decl *D) {
1970b57cec5SDimitry Andric     switch (D->getKind()) {
1980b57cec5SDimitry Andric     default:
1990b57cec5SDimitry Andric       break;
2000b57cec5SDimitry Andric     case Decl::Function:
2010b57cec5SDimitry Andric     case Decl::CXXMethod:
2020b57cec5SDimitry Andric     case Decl::CXXConstructor:
2030b57cec5SDimitry Andric     case Decl::CXXDestructor:
2040b57cec5SDimitry Andric     case Decl::CXXConversion:
2050b57cec5SDimitry Andric     case Decl::ObjCMethod:
2060b57cec5SDimitry Andric     case Decl::Block:
2070b57cec5SDimitry Andric     case Decl::Captured:
2080b57cec5SDimitry Andric       CounterMap[D->getBody()] = NextCounter++;
2090b57cec5SDimitry Andric       break;
2100b57cec5SDimitry Andric     }
2110b57cec5SDimitry Andric     return true;
2120b57cec5SDimitry Andric   }
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   /// If \p S gets a fresh counter, update the counter mappings. Return the
2150b57cec5SDimitry Andric   /// V1 hash of \p S.
updateCounterMappings__anonfabf342f0111::MapRegionCounters2160b57cec5SDimitry Andric   PGOHash::HashType updateCounterMappings(Stmt *S) {
2170b57cec5SDimitry Andric     auto Type = getHashType(PGO_HASH_V1, S);
2180b57cec5SDimitry Andric     if (Type != PGOHash::None)
2190b57cec5SDimitry Andric       CounterMap[S] = NextCounter++;
2200b57cec5SDimitry Andric     return Type;
2210b57cec5SDimitry Andric   }
2220b57cec5SDimitry Andric 
223cdc20ff6SDimitry Andric   /// The following stacks are used with dataTraverseStmtPre() and
224cdc20ff6SDimitry Andric   /// dataTraverseStmtPost() to track the depth of nested logical operators in a
225cdc20ff6SDimitry Andric   /// boolean expression in a function.  The ultimate purpose is to keep track
226cdc20ff6SDimitry Andric   /// of the number of leaf-level conditions in the boolean expression so that a
227cdc20ff6SDimitry Andric   /// profile bitmap can be allocated based on that number.
228cdc20ff6SDimitry Andric   ///
229cdc20ff6SDimitry Andric   /// The stacks are also used to find error cases and notify the user.  A
230cdc20ff6SDimitry Andric   /// standard logical operator nest for a boolean expression could be in a form
231cdc20ff6SDimitry Andric   /// similar to this: "x = a && b && c && (d || f)"
232cdc20ff6SDimitry Andric   unsigned NumCond = 0;
233cdc20ff6SDimitry Andric   bool SplitNestedLogicalOp = false;
234cdc20ff6SDimitry Andric   SmallVector<const Stmt *, 16> NonLogOpStack;
235cdc20ff6SDimitry Andric   SmallVector<const BinaryOperator *, 16> LogOpStack;
236cdc20ff6SDimitry Andric 
237cdc20ff6SDimitry Andric   // Hook: dataTraverseStmtPre() is invoked prior to visiting an AST Stmt node.
dataTraverseStmtPre__anonfabf342f0111::MapRegionCounters238cdc20ff6SDimitry Andric   bool dataTraverseStmtPre(Stmt *S) {
239cdc20ff6SDimitry Andric     /// If MC/DC is not enabled, MCDCMaxCond will be set to 0. Do nothing.
240cdc20ff6SDimitry Andric     if (MCDCMaxCond == 0)
241cdc20ff6SDimitry Andric       return true;
242cdc20ff6SDimitry Andric 
243*471f3ba4SDimitry Andric     /// At the top of the logical operator nest, reset the number of conditions,
244*471f3ba4SDimitry Andric     /// also forget previously seen split nesting cases.
245*471f3ba4SDimitry Andric     if (LogOpStack.empty()) {
246cdc20ff6SDimitry Andric       NumCond = 0;
247*471f3ba4SDimitry Andric       SplitNestedLogicalOp = false;
248*471f3ba4SDimitry Andric     }
249cdc20ff6SDimitry Andric 
250cdc20ff6SDimitry Andric     if (const Expr *E = dyn_cast<Expr>(S)) {
251cdc20ff6SDimitry Andric       const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E->IgnoreParens());
252cdc20ff6SDimitry Andric       if (BinOp && BinOp->isLogicalOp()) {
253cdc20ff6SDimitry Andric         /// Check for "split-nested" logical operators. This happens when a new
254cdc20ff6SDimitry Andric         /// boolean expression logical-op nest is encountered within an existing
255cdc20ff6SDimitry Andric         /// boolean expression, separated by a non-logical operator.  For
256cdc20ff6SDimitry Andric         /// example, in "x = (a && b && c && foo(d && f))", the "d && f" case
257cdc20ff6SDimitry Andric         /// starts a new boolean expression that is separated from the other
258cdc20ff6SDimitry Andric         /// conditions by the operator foo(). Split-nested cases are not
259cdc20ff6SDimitry Andric         /// supported by MC/DC.
260cdc20ff6SDimitry Andric         SplitNestedLogicalOp = SplitNestedLogicalOp || !NonLogOpStack.empty();
261cdc20ff6SDimitry Andric 
262cdc20ff6SDimitry Andric         LogOpStack.push_back(BinOp);
263cdc20ff6SDimitry Andric         return true;
264cdc20ff6SDimitry Andric       }
265cdc20ff6SDimitry Andric     }
266cdc20ff6SDimitry Andric 
267cdc20ff6SDimitry Andric     /// Keep track of non-logical operators. These are OK as long as we don't
268cdc20ff6SDimitry Andric     /// encounter a new logical operator after seeing one.
269cdc20ff6SDimitry Andric     if (!LogOpStack.empty())
270cdc20ff6SDimitry Andric       NonLogOpStack.push_back(S);
271cdc20ff6SDimitry Andric 
272cdc20ff6SDimitry Andric     return true;
273cdc20ff6SDimitry Andric   }
274cdc20ff6SDimitry Andric 
275cdc20ff6SDimitry Andric   // Hook: dataTraverseStmtPost() is invoked by the AST visitor after visiting
276cdc20ff6SDimitry Andric   // an AST Stmt node.  MC/DC will use it to to signal when the top of a
277cdc20ff6SDimitry Andric   // logical operation (boolean expression) nest is encountered.
dataTraverseStmtPost__anonfabf342f0111::MapRegionCounters278cdc20ff6SDimitry Andric   bool dataTraverseStmtPost(Stmt *S) {
279cdc20ff6SDimitry Andric     /// If MC/DC is not enabled, MCDCMaxCond will be set to 0. Do nothing.
280cdc20ff6SDimitry Andric     if (MCDCMaxCond == 0)
281cdc20ff6SDimitry Andric       return true;
282cdc20ff6SDimitry Andric 
283cdc20ff6SDimitry Andric     if (const Expr *E = dyn_cast<Expr>(S)) {
284cdc20ff6SDimitry Andric       const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E->IgnoreParens());
285cdc20ff6SDimitry Andric       if (BinOp && BinOp->isLogicalOp()) {
286cdc20ff6SDimitry Andric         assert(LogOpStack.back() == BinOp);
287cdc20ff6SDimitry Andric         LogOpStack.pop_back();
288cdc20ff6SDimitry Andric 
289cdc20ff6SDimitry Andric         /// At the top of logical operator nest:
290cdc20ff6SDimitry Andric         if (LogOpStack.empty()) {
291cdc20ff6SDimitry Andric           /// Was the "split-nested" logical operator case encountered?
292cdc20ff6SDimitry Andric           if (SplitNestedLogicalOp) {
293cdc20ff6SDimitry Andric             unsigned DiagID = Diag.getCustomDiagID(
294cdc20ff6SDimitry Andric                 DiagnosticsEngine::Warning,
295cdc20ff6SDimitry Andric                 "unsupported MC/DC boolean expression; "
296cdc20ff6SDimitry Andric                 "contains an operation with a nested boolean expression. "
297cdc20ff6SDimitry Andric                 "Expression will not be covered");
298cdc20ff6SDimitry Andric             Diag.Report(S->getBeginLoc(), DiagID);
299*471f3ba4SDimitry Andric             return true;
300cdc20ff6SDimitry Andric           }
301cdc20ff6SDimitry Andric 
302cdc20ff6SDimitry Andric           /// Was the maximum number of conditions encountered?
303cdc20ff6SDimitry Andric           if (NumCond > MCDCMaxCond) {
304cdc20ff6SDimitry Andric             unsigned DiagID = Diag.getCustomDiagID(
305cdc20ff6SDimitry Andric                 DiagnosticsEngine::Warning,
306cdc20ff6SDimitry Andric                 "unsupported MC/DC boolean expression; "
307cdc20ff6SDimitry Andric                 "number of conditions (%0) exceeds max (%1). "
308cdc20ff6SDimitry Andric                 "Expression will not be covered");
309cdc20ff6SDimitry Andric             Diag.Report(S->getBeginLoc(), DiagID) << NumCond << MCDCMaxCond;
310*471f3ba4SDimitry Andric             return true;
311cdc20ff6SDimitry Andric           }
312cdc20ff6SDimitry Andric 
313cdc20ff6SDimitry Andric           // Otherwise, allocate the number of bytes required for the bitmap
314cdc20ff6SDimitry Andric           // based on the number of conditions. Must be at least 1-byte long.
315cdc20ff6SDimitry Andric           MCDCBitmapMap[BinOp] = NextMCDCBitmapIdx;
316cdc20ff6SDimitry Andric           unsigned SizeInBits = std::max<unsigned>(1L << NumCond, CHAR_BIT);
317cdc20ff6SDimitry Andric           NextMCDCBitmapIdx += SizeInBits / CHAR_BIT;
318cdc20ff6SDimitry Andric         }
319cdc20ff6SDimitry Andric         return true;
320cdc20ff6SDimitry Andric       }
321cdc20ff6SDimitry Andric     }
322cdc20ff6SDimitry Andric 
323cdc20ff6SDimitry Andric     if (!LogOpStack.empty())
324cdc20ff6SDimitry Andric       NonLogOpStack.pop_back();
325cdc20ff6SDimitry Andric 
326cdc20ff6SDimitry Andric     return true;
327cdc20ff6SDimitry Andric   }
328cdc20ff6SDimitry Andric 
329e8d8bef9SDimitry Andric   /// The RHS of all logical operators gets a fresh counter in order to count
330e8d8bef9SDimitry Andric   /// how many times the RHS evaluates to true or false, depending on the
331e8d8bef9SDimitry Andric   /// semantics of the operator. This is only valid for ">= v7" of the profile
332cdc20ff6SDimitry Andric   /// version so that we facilitate backward compatibility. In addition, in
333cdc20ff6SDimitry Andric   /// order to use MC/DC, count the number of total LHS and RHS conditions.
VisitBinaryOperator__anonfabf342f0111::MapRegionCounters334e8d8bef9SDimitry Andric   bool VisitBinaryOperator(BinaryOperator *S) {
335cdc20ff6SDimitry Andric     if (S->isLogicalOp()) {
336cdc20ff6SDimitry Andric       if (CodeGenFunction::isInstrumentedCondition(S->getLHS()))
337cdc20ff6SDimitry Andric         NumCond++;
338cdc20ff6SDimitry Andric 
339cdc20ff6SDimitry Andric       if (CodeGenFunction::isInstrumentedCondition(S->getRHS())) {
340e8d8bef9SDimitry Andric         if (ProfileVersion >= llvm::IndexedInstrProf::Version7)
341e8d8bef9SDimitry Andric           CounterMap[S->getRHS()] = NextCounter++;
342cdc20ff6SDimitry Andric 
343cdc20ff6SDimitry Andric         NumCond++;
344cdc20ff6SDimitry Andric       }
345cdc20ff6SDimitry Andric     }
346e8d8bef9SDimitry Andric     return Base::VisitBinaryOperator(S);
347e8d8bef9SDimitry Andric   }
348e8d8bef9SDimitry Andric 
3490b57cec5SDimitry Andric   /// Include \p S in the function hash.
VisitStmt__anonfabf342f0111::MapRegionCounters3500b57cec5SDimitry Andric   bool VisitStmt(Stmt *S) {
3510b57cec5SDimitry Andric     auto Type = updateCounterMappings(S);
3520b57cec5SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)
3530b57cec5SDimitry Andric       Type = getHashType(Hash.getHashVersion(), S);
3540b57cec5SDimitry Andric     if (Type != PGOHash::None)
3550b57cec5SDimitry Andric       Hash.combine(Type);
3560b57cec5SDimitry Andric     return true;
3570b57cec5SDimitry Andric   }
3580b57cec5SDimitry Andric 
TraverseIfStmt__anonfabf342f0111::MapRegionCounters3590b57cec5SDimitry Andric   bool TraverseIfStmt(IfStmt *If) {
3600b57cec5SDimitry Andric     // If we used the V1 hash, use the default traversal.
3610b57cec5SDimitry Andric     if (Hash.getHashVersion() == PGO_HASH_V1)
3620b57cec5SDimitry Andric       return Base::TraverseIfStmt(If);
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric     // Otherwise, keep track of which branch we're in while traversing.
3650b57cec5SDimitry Andric     VisitStmt(If);
3660b57cec5SDimitry Andric     for (Stmt *CS : If->children()) {
3670b57cec5SDimitry Andric       if (!CS)
3680b57cec5SDimitry Andric         continue;
3690b57cec5SDimitry Andric       if (CS == If->getThen())
3700b57cec5SDimitry Andric         Hash.combine(PGOHash::IfThenBranch);
3710b57cec5SDimitry Andric       else if (CS == If->getElse())
3720b57cec5SDimitry Andric         Hash.combine(PGOHash::IfElseBranch);
3730b57cec5SDimitry Andric       TraverseStmt(CS);
3740b57cec5SDimitry Andric     }
3750b57cec5SDimitry Andric     Hash.combine(PGOHash::EndOfScope);
3760b57cec5SDimitry Andric     return true;
3770b57cec5SDimitry Andric   }
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric // If the statement type \p N is nestable, and its nesting impacts profile
3800b57cec5SDimitry Andric // stability, define a custom traversal which tracks the end of the statement
3810b57cec5SDimitry Andric // in the hash (provided we're not using the V1 hash).
3820b57cec5SDimitry Andric #define DEFINE_NESTABLE_TRAVERSAL(N)                                           \
3830b57cec5SDimitry Andric   bool Traverse##N(N *S) {                                                     \
3840b57cec5SDimitry Andric     Base::Traverse##N(S);                                                      \
3850b57cec5SDimitry Andric     if (Hash.getHashVersion() != PGO_HASH_V1)                                  \
3860b57cec5SDimitry Andric       Hash.combine(PGOHash::EndOfScope);                                       \
3870b57cec5SDimitry Andric     return true;                                                               \
3880b57cec5SDimitry Andric   }
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(WhileStmt)
DEFINE_NESTABLE_TRAVERSAL__anonfabf342f0111::MapRegionCounters3910b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(DoStmt)
3920b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(ForStmt)
3930b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXForRangeStmt)
3940b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(ObjCForCollectionStmt)
3950b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXTryStmt)
3960b57cec5SDimitry Andric   DEFINE_NESTABLE_TRAVERSAL(CXXCatchStmt)
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric   /// Get version \p HashVersion of the PGO hash for \p S.
3990b57cec5SDimitry Andric   PGOHash::HashType getHashType(PGOHashVersion HashVersion, const Stmt *S) {
4000b57cec5SDimitry Andric     switch (S->getStmtClass()) {
4010b57cec5SDimitry Andric     default:
4020b57cec5SDimitry Andric       break;
4030b57cec5SDimitry Andric     case Stmt::LabelStmtClass:
4040b57cec5SDimitry Andric       return PGOHash::LabelStmt;
4050b57cec5SDimitry Andric     case Stmt::WhileStmtClass:
4060b57cec5SDimitry Andric       return PGOHash::WhileStmt;
4070b57cec5SDimitry Andric     case Stmt::DoStmtClass:
4080b57cec5SDimitry Andric       return PGOHash::DoStmt;
4090b57cec5SDimitry Andric     case Stmt::ForStmtClass:
4100b57cec5SDimitry Andric       return PGOHash::ForStmt;
4110b57cec5SDimitry Andric     case Stmt::CXXForRangeStmtClass:
4120b57cec5SDimitry Andric       return PGOHash::CXXForRangeStmt;
4130b57cec5SDimitry Andric     case Stmt::ObjCForCollectionStmtClass:
4140b57cec5SDimitry Andric       return PGOHash::ObjCForCollectionStmt;
4150b57cec5SDimitry Andric     case Stmt::SwitchStmtClass:
4160b57cec5SDimitry Andric       return PGOHash::SwitchStmt;
4170b57cec5SDimitry Andric     case Stmt::CaseStmtClass:
4180b57cec5SDimitry Andric       return PGOHash::CaseStmt;
4190b57cec5SDimitry Andric     case Stmt::DefaultStmtClass:
4200b57cec5SDimitry Andric       return PGOHash::DefaultStmt;
4210b57cec5SDimitry Andric     case Stmt::IfStmtClass:
4220b57cec5SDimitry Andric       return PGOHash::IfStmt;
4230b57cec5SDimitry Andric     case Stmt::CXXTryStmtClass:
4240b57cec5SDimitry Andric       return PGOHash::CXXTryStmt;
4250b57cec5SDimitry Andric     case Stmt::CXXCatchStmtClass:
4260b57cec5SDimitry Andric       return PGOHash::CXXCatchStmt;
4270b57cec5SDimitry Andric     case Stmt::ConditionalOperatorClass:
4280b57cec5SDimitry Andric       return PGOHash::ConditionalOperator;
4290b57cec5SDimitry Andric     case Stmt::BinaryConditionalOperatorClass:
4300b57cec5SDimitry Andric       return PGOHash::BinaryConditionalOperator;
4310b57cec5SDimitry Andric     case Stmt::BinaryOperatorClass: {
4320b57cec5SDimitry Andric       const BinaryOperator *BO = cast<BinaryOperator>(S);
4330b57cec5SDimitry Andric       if (BO->getOpcode() == BO_LAnd)
4340b57cec5SDimitry Andric         return PGOHash::BinaryOperatorLAnd;
4350b57cec5SDimitry Andric       if (BO->getOpcode() == BO_LOr)
4360b57cec5SDimitry Andric         return PGOHash::BinaryOperatorLOr;
4375ffd83dbSDimitry Andric       if (HashVersion >= PGO_HASH_V2) {
4380b57cec5SDimitry Andric         switch (BO->getOpcode()) {
4390b57cec5SDimitry Andric         default:
4400b57cec5SDimitry Andric           break;
4410b57cec5SDimitry Andric         case BO_LT:
4420b57cec5SDimitry Andric           return PGOHash::BinaryOperatorLT;
4430b57cec5SDimitry Andric         case BO_GT:
4440b57cec5SDimitry Andric           return PGOHash::BinaryOperatorGT;
4450b57cec5SDimitry Andric         case BO_LE:
4460b57cec5SDimitry Andric           return PGOHash::BinaryOperatorLE;
4470b57cec5SDimitry Andric         case BO_GE:
4480b57cec5SDimitry Andric           return PGOHash::BinaryOperatorGE;
4490b57cec5SDimitry Andric         case BO_EQ:
4500b57cec5SDimitry Andric           return PGOHash::BinaryOperatorEQ;
4510b57cec5SDimitry Andric         case BO_NE:
4520b57cec5SDimitry Andric           return PGOHash::BinaryOperatorNE;
4530b57cec5SDimitry Andric         }
4540b57cec5SDimitry Andric       }
4550b57cec5SDimitry Andric       break;
4560b57cec5SDimitry Andric     }
4570b57cec5SDimitry Andric     }
4580b57cec5SDimitry Andric 
4595ffd83dbSDimitry Andric     if (HashVersion >= PGO_HASH_V2) {
4600b57cec5SDimitry Andric       switch (S->getStmtClass()) {
4610b57cec5SDimitry Andric       default:
4620b57cec5SDimitry Andric         break;
4630b57cec5SDimitry Andric       case Stmt::GotoStmtClass:
4640b57cec5SDimitry Andric         return PGOHash::GotoStmt;
4650b57cec5SDimitry Andric       case Stmt::IndirectGotoStmtClass:
4660b57cec5SDimitry Andric         return PGOHash::IndirectGotoStmt;
4670b57cec5SDimitry Andric       case Stmt::BreakStmtClass:
4680b57cec5SDimitry Andric         return PGOHash::BreakStmt;
4690b57cec5SDimitry Andric       case Stmt::ContinueStmtClass:
4700b57cec5SDimitry Andric         return PGOHash::ContinueStmt;
4710b57cec5SDimitry Andric       case Stmt::ReturnStmtClass:
4720b57cec5SDimitry Andric         return PGOHash::ReturnStmt;
4730b57cec5SDimitry Andric       case Stmt::CXXThrowExprClass:
4740b57cec5SDimitry Andric         return PGOHash::ThrowExpr;
4750b57cec5SDimitry Andric       case Stmt::UnaryOperatorClass: {
4760b57cec5SDimitry Andric         const UnaryOperator *UO = cast<UnaryOperator>(S);
4770b57cec5SDimitry Andric         if (UO->getOpcode() == UO_LNot)
4780b57cec5SDimitry Andric           return PGOHash::UnaryOperatorLNot;
4790b57cec5SDimitry Andric         break;
4800b57cec5SDimitry Andric       }
4810b57cec5SDimitry Andric       }
4820b57cec5SDimitry Andric     }
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric     return PGOHash::None;
4850b57cec5SDimitry Andric   }
4860b57cec5SDimitry Andric };
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric /// A StmtVisitor that propagates the raw counts through the AST and
4890b57cec5SDimitry Andric /// records the count at statements where the value may change.
4900b57cec5SDimitry Andric struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
4910b57cec5SDimitry Andric   /// PGO state.
4920b57cec5SDimitry Andric   CodeGenPGO &PGO;
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric   /// A flag that is set when the current count should be recorded on the
4950b57cec5SDimitry Andric   /// next statement, such as at the exit of a loop.
4960b57cec5SDimitry Andric   bool RecordNextStmtCount;
4970b57cec5SDimitry Andric 
4980b57cec5SDimitry Andric   /// The count at the current location in the traversal.
4990b57cec5SDimitry Andric   uint64_t CurrentCount;
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric   /// The map of statements to count values.
5020b57cec5SDimitry Andric   llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric   /// BreakContinueStack - Keep counts of breaks and continues inside loops.
5050b57cec5SDimitry Andric   struct BreakContinue {
506c9157d92SDimitry Andric     uint64_t BreakCount = 0;
507c9157d92SDimitry Andric     uint64_t ContinueCount = 0;
508c9157d92SDimitry Andric     BreakContinue() = default;
5090b57cec5SDimitry Andric   };
5100b57cec5SDimitry Andric   SmallVector<BreakContinue, 8> BreakContinueStack;
5110b57cec5SDimitry Andric 
ComputeRegionCounts__anonfabf342f0111::ComputeRegionCounts5120b57cec5SDimitry Andric   ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
5130b57cec5SDimitry Andric                       CodeGenPGO &PGO)
5140b57cec5SDimitry Andric       : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
5150b57cec5SDimitry Andric 
RecordStmtCount__anonfabf342f0111::ComputeRegionCounts5160b57cec5SDimitry Andric   void RecordStmtCount(const Stmt *S) {
5170b57cec5SDimitry Andric     if (RecordNextStmtCount) {
5180b57cec5SDimitry Andric       CountMap[S] = CurrentCount;
5190b57cec5SDimitry Andric       RecordNextStmtCount = false;
5200b57cec5SDimitry Andric     }
5210b57cec5SDimitry Andric   }
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric   /// Set and return the current count.
setCount__anonfabf342f0111::ComputeRegionCounts5240b57cec5SDimitry Andric   uint64_t setCount(uint64_t Count) {
5250b57cec5SDimitry Andric     CurrentCount = Count;
5260b57cec5SDimitry Andric     return Count;
5270b57cec5SDimitry Andric   }
5280b57cec5SDimitry Andric 
VisitStmt__anonfabf342f0111::ComputeRegionCounts5290b57cec5SDimitry Andric   void VisitStmt(const Stmt *S) {
5300b57cec5SDimitry Andric     RecordStmtCount(S);
5310b57cec5SDimitry Andric     for (const Stmt *Child : S->children())
5320b57cec5SDimitry Andric       if (Child)
5330b57cec5SDimitry Andric         this->Visit(Child);
5340b57cec5SDimitry Andric   }
5350b57cec5SDimitry Andric 
VisitFunctionDecl__anonfabf342f0111::ComputeRegionCounts5360b57cec5SDimitry Andric   void VisitFunctionDecl(const FunctionDecl *D) {
5370b57cec5SDimitry Andric     // Counter tracks entry to the function body.
5380b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
5390b57cec5SDimitry Andric     CountMap[D->getBody()] = BodyCount;
5400b57cec5SDimitry Andric     Visit(D->getBody());
5410b57cec5SDimitry Andric   }
5420b57cec5SDimitry Andric 
5430b57cec5SDimitry Andric   // Skip lambda expressions. We visit these as FunctionDecls when we're
5440b57cec5SDimitry Andric   // generating them and aren't interested in the body when generating a
5450b57cec5SDimitry Andric   // parent context.
VisitLambdaExpr__anonfabf342f0111::ComputeRegionCounts5460b57cec5SDimitry Andric   void VisitLambdaExpr(const LambdaExpr *LE) {}
5470b57cec5SDimitry Andric 
VisitCapturedDecl__anonfabf342f0111::ComputeRegionCounts5480b57cec5SDimitry Andric   void VisitCapturedDecl(const CapturedDecl *D) {
5490b57cec5SDimitry Andric     // Counter tracks entry to the capture body.
5500b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
5510b57cec5SDimitry Andric     CountMap[D->getBody()] = BodyCount;
5520b57cec5SDimitry Andric     Visit(D->getBody());
5530b57cec5SDimitry Andric   }
5540b57cec5SDimitry Andric 
VisitObjCMethodDecl__anonfabf342f0111::ComputeRegionCounts5550b57cec5SDimitry Andric   void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
5560b57cec5SDimitry Andric     // Counter tracks entry to the method body.
5570b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
5580b57cec5SDimitry Andric     CountMap[D->getBody()] = BodyCount;
5590b57cec5SDimitry Andric     Visit(D->getBody());
5600b57cec5SDimitry Andric   }
5610b57cec5SDimitry Andric 
VisitBlockDecl__anonfabf342f0111::ComputeRegionCounts5620b57cec5SDimitry Andric   void VisitBlockDecl(const BlockDecl *D) {
5630b57cec5SDimitry Andric     // Counter tracks entry to the block body.
5640b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody()));
5650b57cec5SDimitry Andric     CountMap[D->getBody()] = BodyCount;
5660b57cec5SDimitry Andric     Visit(D->getBody());
5670b57cec5SDimitry Andric   }
5680b57cec5SDimitry Andric 
VisitReturnStmt__anonfabf342f0111::ComputeRegionCounts5690b57cec5SDimitry Andric   void VisitReturnStmt(const ReturnStmt *S) {
5700b57cec5SDimitry Andric     RecordStmtCount(S);
5710b57cec5SDimitry Andric     if (S->getRetValue())
5720b57cec5SDimitry Andric       Visit(S->getRetValue());
5730b57cec5SDimitry Andric     CurrentCount = 0;
5740b57cec5SDimitry Andric     RecordNextStmtCount = true;
5750b57cec5SDimitry Andric   }
5760b57cec5SDimitry Andric 
VisitCXXThrowExpr__anonfabf342f0111::ComputeRegionCounts5770b57cec5SDimitry Andric   void VisitCXXThrowExpr(const CXXThrowExpr *E) {
5780b57cec5SDimitry Andric     RecordStmtCount(E);
5790b57cec5SDimitry Andric     if (E->getSubExpr())
5800b57cec5SDimitry Andric       Visit(E->getSubExpr());
5810b57cec5SDimitry Andric     CurrentCount = 0;
5820b57cec5SDimitry Andric     RecordNextStmtCount = true;
5830b57cec5SDimitry Andric   }
5840b57cec5SDimitry Andric 
VisitGotoStmt__anonfabf342f0111::ComputeRegionCounts5850b57cec5SDimitry Andric   void VisitGotoStmt(const GotoStmt *S) {
5860b57cec5SDimitry Andric     RecordStmtCount(S);
5870b57cec5SDimitry Andric     CurrentCount = 0;
5880b57cec5SDimitry Andric     RecordNextStmtCount = true;
5890b57cec5SDimitry Andric   }
5900b57cec5SDimitry Andric 
VisitLabelStmt__anonfabf342f0111::ComputeRegionCounts5910b57cec5SDimitry Andric   void VisitLabelStmt(const LabelStmt *S) {
5920b57cec5SDimitry Andric     RecordNextStmtCount = false;
5930b57cec5SDimitry Andric     // Counter tracks the block following the label.
5940b57cec5SDimitry Andric     uint64_t BlockCount = setCount(PGO.getRegionCount(S));
5950b57cec5SDimitry Andric     CountMap[S] = BlockCount;
5960b57cec5SDimitry Andric     Visit(S->getSubStmt());
5970b57cec5SDimitry Andric   }
5980b57cec5SDimitry Andric 
VisitBreakStmt__anonfabf342f0111::ComputeRegionCounts5990b57cec5SDimitry Andric   void VisitBreakStmt(const BreakStmt *S) {
6000b57cec5SDimitry Andric     RecordStmtCount(S);
6010b57cec5SDimitry Andric     assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
6020b57cec5SDimitry Andric     BreakContinueStack.back().BreakCount += CurrentCount;
6030b57cec5SDimitry Andric     CurrentCount = 0;
6040b57cec5SDimitry Andric     RecordNextStmtCount = true;
6050b57cec5SDimitry Andric   }
6060b57cec5SDimitry Andric 
VisitContinueStmt__anonfabf342f0111::ComputeRegionCounts6070b57cec5SDimitry Andric   void VisitContinueStmt(const ContinueStmt *S) {
6080b57cec5SDimitry Andric     RecordStmtCount(S);
6090b57cec5SDimitry Andric     assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
6100b57cec5SDimitry Andric     BreakContinueStack.back().ContinueCount += CurrentCount;
6110b57cec5SDimitry Andric     CurrentCount = 0;
6120b57cec5SDimitry Andric     RecordNextStmtCount = true;
6130b57cec5SDimitry Andric   }
6140b57cec5SDimitry Andric 
VisitWhileStmt__anonfabf342f0111::ComputeRegionCounts6150b57cec5SDimitry Andric   void VisitWhileStmt(const WhileStmt *S) {
6160b57cec5SDimitry Andric     RecordStmtCount(S);
6170b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
6180b57cec5SDimitry Andric 
6190b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
6200b57cec5SDimitry Andric     // Visit the body region first so the break/continue adjustments can be
6210b57cec5SDimitry Andric     // included when visiting the condition.
6220b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
6230b57cec5SDimitry Andric     CountMap[S->getBody()] = CurrentCount;
6240b57cec5SDimitry Andric     Visit(S->getBody());
6250b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
6260b57cec5SDimitry Andric 
6270b57cec5SDimitry Andric     // ...then go back and propagate counts through the condition. The count
6280b57cec5SDimitry Andric     // at the start of the condition is the sum of the incoming edges,
6290b57cec5SDimitry Andric     // the backedge from the end of the loop body, and the edges from
6300b57cec5SDimitry Andric     // continue statements.
6310b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
6320b57cec5SDimitry Andric     uint64_t CondCount =
6330b57cec5SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
6340b57cec5SDimitry Andric     CountMap[S->getCond()] = CondCount;
6350b57cec5SDimitry Andric     Visit(S->getCond());
6360b57cec5SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
6370b57cec5SDimitry Andric     RecordNextStmtCount = true;
6380b57cec5SDimitry Andric   }
6390b57cec5SDimitry Andric 
VisitDoStmt__anonfabf342f0111::ComputeRegionCounts6400b57cec5SDimitry Andric   void VisitDoStmt(const DoStmt *S) {
6410b57cec5SDimitry Andric     RecordStmtCount(S);
6420b57cec5SDimitry Andric     uint64_t LoopCount = PGO.getRegionCount(S);
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
6450b57cec5SDimitry Andric     // The count doesn't include the fallthrough from the parent scope. Add it.
6460b57cec5SDimitry Andric     uint64_t BodyCount = setCount(LoopCount + CurrentCount);
6470b57cec5SDimitry Andric     CountMap[S->getBody()] = BodyCount;
6480b57cec5SDimitry Andric     Visit(S->getBody());
6490b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
6500b57cec5SDimitry Andric 
6510b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
6520b57cec5SDimitry Andric     // The count at the start of the condition is equal to the count at the
6530b57cec5SDimitry Andric     // end of the body, plus any continues.
6540b57cec5SDimitry Andric     uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount);
6550b57cec5SDimitry Andric     CountMap[S->getCond()] = CondCount;
6560b57cec5SDimitry Andric     Visit(S->getCond());
6570b57cec5SDimitry Andric     setCount(BC.BreakCount + CondCount - LoopCount);
6580b57cec5SDimitry Andric     RecordNextStmtCount = true;
6590b57cec5SDimitry Andric   }
6600b57cec5SDimitry Andric 
VisitForStmt__anonfabf342f0111::ComputeRegionCounts6610b57cec5SDimitry Andric   void VisitForStmt(const ForStmt *S) {
6620b57cec5SDimitry Andric     RecordStmtCount(S);
6630b57cec5SDimitry Andric     if (S->getInit())
6640b57cec5SDimitry Andric       Visit(S->getInit());
6650b57cec5SDimitry Andric 
6660b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
6670b57cec5SDimitry Andric 
6680b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
6690b57cec5SDimitry Andric     // Visit the body region first. (This is basically the same as a while
6700b57cec5SDimitry Andric     // loop; see further comments in VisitWhileStmt.)
6710b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
6720b57cec5SDimitry Andric     CountMap[S->getBody()] = BodyCount;
6730b57cec5SDimitry Andric     Visit(S->getBody());
6740b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
6750b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
6760b57cec5SDimitry Andric 
6770b57cec5SDimitry Andric     // The increment is essentially part of the body but it needs to include
6780b57cec5SDimitry Andric     // the count for all the continue statements.
6790b57cec5SDimitry Andric     if (S->getInc()) {
6800b57cec5SDimitry Andric       uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
6810b57cec5SDimitry Andric       CountMap[S->getInc()] = IncCount;
6820b57cec5SDimitry Andric       Visit(S->getInc());
6830b57cec5SDimitry Andric     }
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric     // ...then go back and propagate counts through the condition.
6860b57cec5SDimitry Andric     uint64_t CondCount =
6870b57cec5SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
6880b57cec5SDimitry Andric     if (S->getCond()) {
6890b57cec5SDimitry Andric       CountMap[S->getCond()] = CondCount;
6900b57cec5SDimitry Andric       Visit(S->getCond());
6910b57cec5SDimitry Andric     }
6920b57cec5SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
6930b57cec5SDimitry Andric     RecordNextStmtCount = true;
6940b57cec5SDimitry Andric   }
6950b57cec5SDimitry Andric 
VisitCXXForRangeStmt__anonfabf342f0111::ComputeRegionCounts6960b57cec5SDimitry Andric   void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
6970b57cec5SDimitry Andric     RecordStmtCount(S);
6980b57cec5SDimitry Andric     if (S->getInit())
6990b57cec5SDimitry Andric       Visit(S->getInit());
7000b57cec5SDimitry Andric     Visit(S->getLoopVarStmt());
7010b57cec5SDimitry Andric     Visit(S->getRangeStmt());
7020b57cec5SDimitry Andric     Visit(S->getBeginStmt());
7030b57cec5SDimitry Andric     Visit(S->getEndStmt());
7040b57cec5SDimitry Andric 
7050b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
7060b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
7070b57cec5SDimitry Andric     // Visit the body region first. (This is basically the same as a while
7080b57cec5SDimitry Andric     // loop; see further comments in VisitWhileStmt.)
7090b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
7100b57cec5SDimitry Andric     CountMap[S->getBody()] = BodyCount;
7110b57cec5SDimitry Andric     Visit(S->getBody());
7120b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
7130b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
7140b57cec5SDimitry Andric 
7150b57cec5SDimitry Andric     // The increment is essentially part of the body but it needs to include
7160b57cec5SDimitry Andric     // the count for all the continue statements.
7170b57cec5SDimitry Andric     uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
7180b57cec5SDimitry Andric     CountMap[S->getInc()] = IncCount;
7190b57cec5SDimitry Andric     Visit(S->getInc());
7200b57cec5SDimitry Andric 
7210b57cec5SDimitry Andric     // ...then go back and propagate counts through the condition.
7220b57cec5SDimitry Andric     uint64_t CondCount =
7230b57cec5SDimitry Andric         setCount(ParentCount + BackedgeCount + BC.ContinueCount);
7240b57cec5SDimitry Andric     CountMap[S->getCond()] = CondCount;
7250b57cec5SDimitry Andric     Visit(S->getCond());
7260b57cec5SDimitry Andric     setCount(BC.BreakCount + CondCount - BodyCount);
7270b57cec5SDimitry Andric     RecordNextStmtCount = true;
7280b57cec5SDimitry Andric   }
7290b57cec5SDimitry Andric 
VisitObjCForCollectionStmt__anonfabf342f0111::ComputeRegionCounts7300b57cec5SDimitry Andric   void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
7310b57cec5SDimitry Andric     RecordStmtCount(S);
7320b57cec5SDimitry Andric     Visit(S->getElement());
7330b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
7340b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
7350b57cec5SDimitry Andric     // Counter tracks the body of the loop.
7360b57cec5SDimitry Andric     uint64_t BodyCount = setCount(PGO.getRegionCount(S));
7370b57cec5SDimitry Andric     CountMap[S->getBody()] = BodyCount;
7380b57cec5SDimitry Andric     Visit(S->getBody());
7390b57cec5SDimitry Andric     uint64_t BackedgeCount = CurrentCount;
7400b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
7410b57cec5SDimitry Andric 
7420b57cec5SDimitry Andric     setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount -
7430b57cec5SDimitry Andric              BodyCount);
7440b57cec5SDimitry Andric     RecordNextStmtCount = true;
7450b57cec5SDimitry Andric   }
7460b57cec5SDimitry Andric 
VisitSwitchStmt__anonfabf342f0111::ComputeRegionCounts7470b57cec5SDimitry Andric   void VisitSwitchStmt(const SwitchStmt *S) {
7480b57cec5SDimitry Andric     RecordStmtCount(S);
7490b57cec5SDimitry Andric     if (S->getInit())
7500b57cec5SDimitry Andric       Visit(S->getInit());
7510b57cec5SDimitry Andric     Visit(S->getCond());
7520b57cec5SDimitry Andric     CurrentCount = 0;
7530b57cec5SDimitry Andric     BreakContinueStack.push_back(BreakContinue());
7540b57cec5SDimitry Andric     Visit(S->getBody());
7550b57cec5SDimitry Andric     // If the switch is inside a loop, add the continue counts.
7560b57cec5SDimitry Andric     BreakContinue BC = BreakContinueStack.pop_back_val();
7570b57cec5SDimitry Andric     if (!BreakContinueStack.empty())
7580b57cec5SDimitry Andric       BreakContinueStack.back().ContinueCount += BC.ContinueCount;
7590b57cec5SDimitry Andric     // Counter tracks the exit block of the switch.
7600b57cec5SDimitry Andric     setCount(PGO.getRegionCount(S));
7610b57cec5SDimitry Andric     RecordNextStmtCount = true;
7620b57cec5SDimitry Andric   }
7630b57cec5SDimitry Andric 
VisitSwitchCase__anonfabf342f0111::ComputeRegionCounts7640b57cec5SDimitry Andric   void VisitSwitchCase(const SwitchCase *S) {
7650b57cec5SDimitry Andric     RecordNextStmtCount = false;
7660b57cec5SDimitry Andric     // Counter for this particular case. This counts only jumps from the
7670b57cec5SDimitry Andric     // switch header and does not include fallthrough from the case before
7680b57cec5SDimitry Andric     // this one.
7690b57cec5SDimitry Andric     uint64_t CaseCount = PGO.getRegionCount(S);
7700b57cec5SDimitry Andric     setCount(CurrentCount + CaseCount);
7710b57cec5SDimitry Andric     // We need the count without fallthrough in the mapping, so it's more useful
7720b57cec5SDimitry Andric     // for branch probabilities.
7730b57cec5SDimitry Andric     CountMap[S] = CaseCount;
7740b57cec5SDimitry Andric     RecordNextStmtCount = true;
7750b57cec5SDimitry Andric     Visit(S->getSubStmt());
7760b57cec5SDimitry Andric   }
7770b57cec5SDimitry Andric 
VisitIfStmt__anonfabf342f0111::ComputeRegionCounts7780b57cec5SDimitry Andric   void VisitIfStmt(const IfStmt *S) {
7790b57cec5SDimitry Andric     RecordStmtCount(S);
780349cc55cSDimitry Andric 
781349cc55cSDimitry Andric     if (S->isConsteval()) {
782349cc55cSDimitry Andric       const Stmt *Stm = S->isNegatedConsteval() ? S->getThen() : S->getElse();
783349cc55cSDimitry Andric       if (Stm)
784349cc55cSDimitry Andric         Visit(Stm);
785349cc55cSDimitry Andric       return;
786349cc55cSDimitry Andric     }
787349cc55cSDimitry Andric 
7880b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
7890b57cec5SDimitry Andric     if (S->getInit())
7900b57cec5SDimitry Andric       Visit(S->getInit());
7910b57cec5SDimitry Andric     Visit(S->getCond());
7920b57cec5SDimitry Andric 
7930b57cec5SDimitry Andric     // Counter tracks the "then" part of an if statement. The count for
7940b57cec5SDimitry Andric     // the "else" part, if it exists, will be calculated from this counter.
7950b57cec5SDimitry Andric     uint64_t ThenCount = setCount(PGO.getRegionCount(S));
7960b57cec5SDimitry Andric     CountMap[S->getThen()] = ThenCount;
7970b57cec5SDimitry Andric     Visit(S->getThen());
7980b57cec5SDimitry Andric     uint64_t OutCount = CurrentCount;
7990b57cec5SDimitry Andric 
8000b57cec5SDimitry Andric     uint64_t ElseCount = ParentCount - ThenCount;
8010b57cec5SDimitry Andric     if (S->getElse()) {
8020b57cec5SDimitry Andric       setCount(ElseCount);
8030b57cec5SDimitry Andric       CountMap[S->getElse()] = ElseCount;
8040b57cec5SDimitry Andric       Visit(S->getElse());
8050b57cec5SDimitry Andric       OutCount += CurrentCount;
8060b57cec5SDimitry Andric     } else
8070b57cec5SDimitry Andric       OutCount += ElseCount;
8080b57cec5SDimitry Andric     setCount(OutCount);
8090b57cec5SDimitry Andric     RecordNextStmtCount = true;
8100b57cec5SDimitry Andric   }
8110b57cec5SDimitry Andric 
VisitCXXTryStmt__anonfabf342f0111::ComputeRegionCounts8120b57cec5SDimitry Andric   void VisitCXXTryStmt(const CXXTryStmt *S) {
8130b57cec5SDimitry Andric     RecordStmtCount(S);
8140b57cec5SDimitry Andric     Visit(S->getTryBlock());
8150b57cec5SDimitry Andric     for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
8160b57cec5SDimitry Andric       Visit(S->getHandler(I));
8170b57cec5SDimitry Andric     // Counter tracks the continuation block of the try statement.
8180b57cec5SDimitry Andric     setCount(PGO.getRegionCount(S));
8190b57cec5SDimitry Andric     RecordNextStmtCount = true;
8200b57cec5SDimitry Andric   }
8210b57cec5SDimitry Andric 
VisitCXXCatchStmt__anonfabf342f0111::ComputeRegionCounts8220b57cec5SDimitry Andric   void VisitCXXCatchStmt(const CXXCatchStmt *S) {
8230b57cec5SDimitry Andric     RecordNextStmtCount = false;
8240b57cec5SDimitry Andric     // Counter tracks the catch statement's handler block.
8250b57cec5SDimitry Andric     uint64_t CatchCount = setCount(PGO.getRegionCount(S));
8260b57cec5SDimitry Andric     CountMap[S] = CatchCount;
8270b57cec5SDimitry Andric     Visit(S->getHandlerBlock());
8280b57cec5SDimitry Andric   }
8290b57cec5SDimitry Andric 
VisitAbstractConditionalOperator__anonfabf342f0111::ComputeRegionCounts8300b57cec5SDimitry Andric   void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
8310b57cec5SDimitry Andric     RecordStmtCount(E);
8320b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
8330b57cec5SDimitry Andric     Visit(E->getCond());
8340b57cec5SDimitry Andric 
8350b57cec5SDimitry Andric     // Counter tracks the "true" part of a conditional operator. The
8360b57cec5SDimitry Andric     // count in the "false" part will be calculated from this counter.
8370b57cec5SDimitry Andric     uint64_t TrueCount = setCount(PGO.getRegionCount(E));
8380b57cec5SDimitry Andric     CountMap[E->getTrueExpr()] = TrueCount;
8390b57cec5SDimitry Andric     Visit(E->getTrueExpr());
8400b57cec5SDimitry Andric     uint64_t OutCount = CurrentCount;
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric     uint64_t FalseCount = setCount(ParentCount - TrueCount);
8430b57cec5SDimitry Andric     CountMap[E->getFalseExpr()] = FalseCount;
8440b57cec5SDimitry Andric     Visit(E->getFalseExpr());
8450b57cec5SDimitry Andric     OutCount += CurrentCount;
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric     setCount(OutCount);
8480b57cec5SDimitry Andric     RecordNextStmtCount = true;
8490b57cec5SDimitry Andric   }
8500b57cec5SDimitry Andric 
VisitBinLAnd__anonfabf342f0111::ComputeRegionCounts8510b57cec5SDimitry Andric   void VisitBinLAnd(const BinaryOperator *E) {
8520b57cec5SDimitry Andric     RecordStmtCount(E);
8530b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
8540b57cec5SDimitry Andric     Visit(E->getLHS());
8550b57cec5SDimitry Andric     // Counter tracks the right hand side of a logical and operator.
8560b57cec5SDimitry Andric     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
8570b57cec5SDimitry Andric     CountMap[E->getRHS()] = RHSCount;
8580b57cec5SDimitry Andric     Visit(E->getRHS());
8590b57cec5SDimitry Andric     setCount(ParentCount + RHSCount - CurrentCount);
8600b57cec5SDimitry Andric     RecordNextStmtCount = true;
8610b57cec5SDimitry Andric   }
8620b57cec5SDimitry Andric 
VisitBinLOr__anonfabf342f0111::ComputeRegionCounts8630b57cec5SDimitry Andric   void VisitBinLOr(const BinaryOperator *E) {
8640b57cec5SDimitry Andric     RecordStmtCount(E);
8650b57cec5SDimitry Andric     uint64_t ParentCount = CurrentCount;
8660b57cec5SDimitry Andric     Visit(E->getLHS());
8670b57cec5SDimitry Andric     // Counter tracks the right hand side of a logical or operator.
8680b57cec5SDimitry Andric     uint64_t RHSCount = setCount(PGO.getRegionCount(E));
8690b57cec5SDimitry Andric     CountMap[E->getRHS()] = RHSCount;
8700b57cec5SDimitry Andric     Visit(E->getRHS());
8710b57cec5SDimitry Andric     setCount(ParentCount + RHSCount - CurrentCount);
8720b57cec5SDimitry Andric     RecordNextStmtCount = true;
8730b57cec5SDimitry Andric   }
8740b57cec5SDimitry Andric };
8750b57cec5SDimitry Andric } // end anonymous namespace
8760b57cec5SDimitry Andric 
combine(HashType Type)8770b57cec5SDimitry Andric void PGOHash::combine(HashType Type) {
8780b57cec5SDimitry Andric   // Check that we never combine 0 and only have six bits.
8790b57cec5SDimitry Andric   assert(Type && "Hash is invalid: unexpected type 0");
8800b57cec5SDimitry Andric   assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric   // Pass through MD5 if enough work has built up.
8830b57cec5SDimitry Andric   if (Count && Count % NumTypesPerWord == 0) {
8840b57cec5SDimitry Andric     using namespace llvm::support;
885c9157d92SDimitry Andric     uint64_t Swapped =
886c9157d92SDimitry Andric         endian::byte_swap<uint64_t, llvm::endianness::little>(Working);
887bdd1243dSDimitry Andric     MD5.update(llvm::ArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
8880b57cec5SDimitry Andric     Working = 0;
8890b57cec5SDimitry Andric   }
8900b57cec5SDimitry Andric 
8910b57cec5SDimitry Andric   // Accumulate the current type.
8920b57cec5SDimitry Andric   ++Count;
8930b57cec5SDimitry Andric   Working = Working << NumBitsPerType | Type;
8940b57cec5SDimitry Andric }
8950b57cec5SDimitry Andric 
finalize()8960b57cec5SDimitry Andric uint64_t PGOHash::finalize() {
8970b57cec5SDimitry Andric   // Use Working as the hash directly if we never used MD5.
8980b57cec5SDimitry Andric   if (Count <= NumTypesPerWord)
8990b57cec5SDimitry Andric     // No need to byte swap here, since none of the math was endian-dependent.
9000b57cec5SDimitry Andric     // This number will be byte-swapped as required on endianness transitions,
9010b57cec5SDimitry Andric     // so we will see the same value on the other side.
9020b57cec5SDimitry Andric     return Working;
9030b57cec5SDimitry Andric 
9040b57cec5SDimitry Andric   // Check for remaining work in Working.
9055ffd83dbSDimitry Andric   if (Working) {
9065ffd83dbSDimitry Andric     // Keep the buggy behavior from v1 and v2 for backward-compatibility. This
9075ffd83dbSDimitry Andric     // is buggy because it converts a uint64_t into an array of uint8_t.
9085ffd83dbSDimitry Andric     if (HashVersion < PGO_HASH_V3) {
9095ffd83dbSDimitry Andric       MD5.update({(uint8_t)Working});
9105ffd83dbSDimitry Andric     } else {
9115ffd83dbSDimitry Andric       using namespace llvm::support;
912c9157d92SDimitry Andric       uint64_t Swapped =
913c9157d92SDimitry Andric           endian::byte_swap<uint64_t, llvm::endianness::little>(Working);
914bdd1243dSDimitry Andric       MD5.update(llvm::ArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
9155ffd83dbSDimitry Andric     }
9165ffd83dbSDimitry Andric   }
9170b57cec5SDimitry Andric 
9180b57cec5SDimitry Andric   // Finalize the MD5 and return the hash.
9190b57cec5SDimitry Andric   llvm::MD5::MD5Result Result;
9200b57cec5SDimitry Andric   MD5.final(Result);
9210b57cec5SDimitry Andric   return Result.low();
9220b57cec5SDimitry Andric }
9230b57cec5SDimitry Andric 
assignRegionCounters(GlobalDecl GD,llvm::Function * Fn)9240b57cec5SDimitry Andric void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
9250b57cec5SDimitry Andric   const Decl *D = GD.getDecl();
9260b57cec5SDimitry Andric   if (!D->hasBody())
9270b57cec5SDimitry Andric     return;
9280b57cec5SDimitry Andric 
929e8d8bef9SDimitry Andric   // Skip CUDA/HIP kernel launch stub functions.
930e8d8bef9SDimitry Andric   if (CGM.getLangOpts().CUDA && !CGM.getLangOpts().CUDAIsDevice &&
931e8d8bef9SDimitry Andric       D->hasAttr<CUDAGlobalAttr>())
932e8d8bef9SDimitry Andric     return;
933e8d8bef9SDimitry Andric 
9340b57cec5SDimitry Andric   bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
9350b57cec5SDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
9360b57cec5SDimitry Andric   if (!InstrumentRegions && !PGOReader)
9370b57cec5SDimitry Andric     return;
9380b57cec5SDimitry Andric   if (D->isImplicit())
9390b57cec5SDimitry Andric     return;
9400b57cec5SDimitry Andric   // Constructors and destructors may be represented by several functions in IR.
9410b57cec5SDimitry Andric   // If so, instrument only base variant, others are implemented by delegation
9420b57cec5SDimitry Andric   // to the base one, it would be counted twice otherwise.
9430b57cec5SDimitry Andric   if (CGM.getTarget().getCXXABI().hasConstructorVariants()) {
9440b57cec5SDimitry Andric     if (const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
9450b57cec5SDimitry Andric       if (GD.getCtorType() != Ctor_Base &&
9460b57cec5SDimitry Andric           CodeGenFunction::IsConstructorDelegationValid(CCD))
9470b57cec5SDimitry Andric         return;
9480b57cec5SDimitry Andric   }
9490b57cec5SDimitry Andric   if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
9500b57cec5SDimitry Andric     return;
9510b57cec5SDimitry Andric 
952fe6060f1SDimitry Andric   CGM.ClearUnusedCoverageMapping(D);
953e8d8bef9SDimitry Andric   if (Fn->hasFnAttribute(llvm::Attribute::NoProfile))
954e8d8bef9SDimitry Andric     return;
955bdd1243dSDimitry Andric   if (Fn->hasFnAttribute(llvm::Attribute::SkipProfile))
956bdd1243dSDimitry Andric     return;
957e8d8bef9SDimitry Andric 
9580b57cec5SDimitry Andric   setFuncName(Fn);
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric   mapRegionCounters(D);
9610b57cec5SDimitry Andric   if (CGM.getCodeGenOpts().CoverageMapping)
9620b57cec5SDimitry Andric     emitCounterRegionMapping(D);
9630b57cec5SDimitry Andric   if (PGOReader) {
9640b57cec5SDimitry Andric     SourceManager &SM = CGM.getContext().getSourceManager();
9650b57cec5SDimitry Andric     loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
9660b57cec5SDimitry Andric     computeRegionCounts(D);
9670b57cec5SDimitry Andric     applyFunctionAttributes(PGOReader, Fn);
9680b57cec5SDimitry Andric   }
9690b57cec5SDimitry Andric }
9700b57cec5SDimitry Andric 
mapRegionCounters(const Decl * D)9710b57cec5SDimitry Andric void CodeGenPGO::mapRegionCounters(const Decl *D) {
9720b57cec5SDimitry Andric   // Use the latest hash version when inserting instrumentation, but use the
9730b57cec5SDimitry Andric   // version in the indexed profile if we're reading PGO data.
9740b57cec5SDimitry Andric   PGOHashVersion HashVersion = PGO_HASH_LATEST;
975e8d8bef9SDimitry Andric   uint64_t ProfileVersion = llvm::IndexedInstrProf::Version;
976e8d8bef9SDimitry Andric   if (auto *PGOReader = CGM.getPGOReader()) {
9770b57cec5SDimitry Andric     HashVersion = getPGOHashVersion(PGOReader, CGM);
978e8d8bef9SDimitry Andric     ProfileVersion = PGOReader->getVersion();
979e8d8bef9SDimitry Andric   }
9800b57cec5SDimitry Andric 
981cdc20ff6SDimitry Andric   // If MC/DC is enabled, set the MaxConditions to a preset value. Otherwise,
982cdc20ff6SDimitry Andric   // set it to zero. This value impacts the number of conditions accepted in a
983cdc20ff6SDimitry Andric   // given boolean expression, which impacts the size of the bitmap used to
984cdc20ff6SDimitry Andric   // track test vector execution for that boolean expression.  Because the
985cdc20ff6SDimitry Andric   // bitmap scales exponentially (2^n) based on the number of conditions seen,
986cdc20ff6SDimitry Andric   // the maximum value is hard-coded at 6 conditions, which is more than enough
987cdc20ff6SDimitry Andric   // for most embedded applications. Setting a maximum value prevents the
988cdc20ff6SDimitry Andric   // bitmap footprint from growing too large without the user's knowledge. In
989cdc20ff6SDimitry Andric   // the future, this value could be adjusted with a command-line option.
990cdc20ff6SDimitry Andric   unsigned MCDCMaxConditions = (CGM.getCodeGenOpts().MCDCCoverage) ? 6 : 0;
991cdc20ff6SDimitry Andric 
9920b57cec5SDimitry Andric   RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
993cdc20ff6SDimitry Andric   RegionMCDCBitmapMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
994cdc20ff6SDimitry Andric   MapRegionCounters Walker(HashVersion, ProfileVersion, *RegionCounterMap,
995cdc20ff6SDimitry Andric                            *RegionMCDCBitmapMap, MCDCMaxConditions,
996cdc20ff6SDimitry Andric                            CGM.getDiags());
9970b57cec5SDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
9980b57cec5SDimitry Andric     Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
9990b57cec5SDimitry Andric   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
10000b57cec5SDimitry Andric     Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
10010b57cec5SDimitry Andric   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
10020b57cec5SDimitry Andric     Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
10030b57cec5SDimitry Andric   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
10040b57cec5SDimitry Andric     Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
10050b57cec5SDimitry Andric   assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
10060b57cec5SDimitry Andric   NumRegionCounters = Walker.NextCounter;
1007cdc20ff6SDimitry Andric   MCDCBitmapBytes = Walker.NextMCDCBitmapIdx;
10080b57cec5SDimitry Andric   FunctionHash = Walker.Hash.finalize();
10090b57cec5SDimitry Andric }
10100b57cec5SDimitry Andric 
skipRegionMappingForDecl(const Decl * D)10110b57cec5SDimitry Andric bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) {
10120b57cec5SDimitry Andric   if (!D->getBody())
10130b57cec5SDimitry Andric     return true;
10140b57cec5SDimitry Andric 
1015e8d8bef9SDimitry Andric   // Skip host-only functions in the CUDA device compilation and device-only
1016e8d8bef9SDimitry Andric   // functions in the host compilation. Just roughly filter them out based on
1017e8d8bef9SDimitry Andric   // the function attributes. If there are effectively host-only or device-only
1018e8d8bef9SDimitry Andric   // ones, their coverage mapping may still be generated.
1019e8d8bef9SDimitry Andric   if (CGM.getLangOpts().CUDA &&
1020e8d8bef9SDimitry Andric       ((CGM.getLangOpts().CUDAIsDevice && !D->hasAttr<CUDADeviceAttr>() &&
1021e8d8bef9SDimitry Andric         !D->hasAttr<CUDAGlobalAttr>()) ||
1022e8d8bef9SDimitry Andric        (!CGM.getLangOpts().CUDAIsDevice &&
1023e8d8bef9SDimitry Andric         (D->hasAttr<CUDAGlobalAttr>() ||
1024e8d8bef9SDimitry Andric          (!D->hasAttr<CUDAHostAttr>() && D->hasAttr<CUDADeviceAttr>())))))
1025e8d8bef9SDimitry Andric     return true;
1026e8d8bef9SDimitry Andric 
10270b57cec5SDimitry Andric   // Don't map the functions in system headers.
10280b57cec5SDimitry Andric   const auto &SM = CGM.getContext().getSourceManager();
10290b57cec5SDimitry Andric   auto Loc = D->getBody()->getBeginLoc();
1030a58f00eaSDimitry Andric   return !SystemHeadersCoverage && SM.isInSystemHeader(Loc);
10310b57cec5SDimitry Andric }
10320b57cec5SDimitry Andric 
emitCounterRegionMapping(const Decl * D)10330b57cec5SDimitry Andric void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
10340b57cec5SDimitry Andric   if (skipRegionMappingForDecl(D))
10350b57cec5SDimitry Andric     return;
10360b57cec5SDimitry Andric 
10370b57cec5SDimitry Andric   std::string CoverageMapping;
10380b57cec5SDimitry Andric   llvm::raw_string_ostream OS(CoverageMapping);
1039cdc20ff6SDimitry Andric   RegionCondIDMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
1040cdc20ff6SDimitry Andric   CoverageMappingGen MappingGen(
1041cdc20ff6SDimitry Andric       *CGM.getCoverageMapping(), CGM.getContext().getSourceManager(),
1042cdc20ff6SDimitry Andric       CGM.getLangOpts(), RegionCounterMap.get(), RegionMCDCBitmapMap.get(),
1043cdc20ff6SDimitry Andric       RegionCondIDMap.get());
10440b57cec5SDimitry Andric   MappingGen.emitCounterMapping(D, OS);
10450b57cec5SDimitry Andric   OS.flush();
10460b57cec5SDimitry Andric 
10470b57cec5SDimitry Andric   if (CoverageMapping.empty())
10480b57cec5SDimitry Andric     return;
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric   CGM.getCoverageMapping()->addFunctionMappingRecord(
10510b57cec5SDimitry Andric       FuncNameVar, FuncName, FunctionHash, CoverageMapping);
10520b57cec5SDimitry Andric }
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric void
emitEmptyCounterMapping(const Decl * D,StringRef Name,llvm::GlobalValue::LinkageTypes Linkage)10550b57cec5SDimitry Andric CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef Name,
10560b57cec5SDimitry Andric                                     llvm::GlobalValue::LinkageTypes Linkage) {
10570b57cec5SDimitry Andric   if (skipRegionMappingForDecl(D))
10580b57cec5SDimitry Andric     return;
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric   std::string CoverageMapping;
10610b57cec5SDimitry Andric   llvm::raw_string_ostream OS(CoverageMapping);
10620b57cec5SDimitry Andric   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
10630b57cec5SDimitry Andric                                 CGM.getContext().getSourceManager(),
10640b57cec5SDimitry Andric                                 CGM.getLangOpts());
10650b57cec5SDimitry Andric   MappingGen.emitEmptyMapping(D, OS);
10660b57cec5SDimitry Andric   OS.flush();
10670b57cec5SDimitry Andric 
10680b57cec5SDimitry Andric   if (CoverageMapping.empty())
10690b57cec5SDimitry Andric     return;
10700b57cec5SDimitry Andric 
10710b57cec5SDimitry Andric   setFuncName(Name, Linkage);
10720b57cec5SDimitry Andric   CGM.getCoverageMapping()->addFunctionMappingRecord(
10730b57cec5SDimitry Andric       FuncNameVar, FuncName, FunctionHash, CoverageMapping, false);
10740b57cec5SDimitry Andric }
10750b57cec5SDimitry Andric 
computeRegionCounts(const Decl * D)10760b57cec5SDimitry Andric void CodeGenPGO::computeRegionCounts(const Decl *D) {
10770b57cec5SDimitry Andric   StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
10780b57cec5SDimitry Andric   ComputeRegionCounts Walker(*StmtCountMap, *this);
10790b57cec5SDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
10800b57cec5SDimitry Andric     Walker.VisitFunctionDecl(FD);
10810b57cec5SDimitry Andric   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
10820b57cec5SDimitry Andric     Walker.VisitObjCMethodDecl(MD);
10830b57cec5SDimitry Andric   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
10840b57cec5SDimitry Andric     Walker.VisitBlockDecl(BD);
10850b57cec5SDimitry Andric   else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
10860b57cec5SDimitry Andric     Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
10870b57cec5SDimitry Andric }
10880b57cec5SDimitry Andric 
10890b57cec5SDimitry Andric void
applyFunctionAttributes(llvm::IndexedInstrProfReader * PGOReader,llvm::Function * Fn)10900b57cec5SDimitry Andric CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
10910b57cec5SDimitry Andric                                     llvm::Function *Fn) {
10920b57cec5SDimitry Andric   if (!haveRegionCounts())
10930b57cec5SDimitry Andric     return;
10940b57cec5SDimitry Andric 
10950b57cec5SDimitry Andric   uint64_t FunctionCount = getRegionCount(nullptr);
10960b57cec5SDimitry Andric   Fn->setEntryCount(FunctionCount);
10970b57cec5SDimitry Andric }
10980b57cec5SDimitry Andric 
emitCounterIncrement(CGBuilderTy & Builder,const Stmt * S,llvm::Value * StepV)10990b57cec5SDimitry Andric void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
11000b57cec5SDimitry Andric                                       llvm::Value *StepV) {
1101c9157d92SDimitry Andric   if (!RegionCounterMap || !Builder.GetInsertBlock())
11020b57cec5SDimitry Andric     return;
11030b57cec5SDimitry Andric 
11040b57cec5SDimitry Andric   unsigned Counter = (*RegionCounterMap)[S];
11050b57cec5SDimitry Andric 
1106c9157d92SDimitry Andric   llvm::Value *Args[] = {FuncNameVar,
11070b57cec5SDimitry Andric                          Builder.getInt64(FunctionHash),
11080b57cec5SDimitry Andric                          Builder.getInt32(NumRegionCounters),
11090b57cec5SDimitry Andric                          Builder.getInt32(Counter), StepV};
11100b57cec5SDimitry Andric   if (!StepV)
11110b57cec5SDimitry Andric     Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
1112bdd1243dSDimitry Andric                        ArrayRef(Args, 4));
11130b57cec5SDimitry Andric   else
11140b57cec5SDimitry Andric     Builder.CreateCall(
11150b57cec5SDimitry Andric         CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment_step),
1116bdd1243dSDimitry Andric         ArrayRef(Args));
11170b57cec5SDimitry Andric }
11180b57cec5SDimitry Andric 
canEmitMCDCCoverage(const CGBuilderTy & Builder)1119cdc20ff6SDimitry Andric bool CodeGenPGO::canEmitMCDCCoverage(const CGBuilderTy &Builder) {
1120cdc20ff6SDimitry Andric   return (CGM.getCodeGenOpts().hasProfileClangInstr() &&
1121cdc20ff6SDimitry Andric           CGM.getCodeGenOpts().MCDCCoverage && Builder.GetInsertBlock());
1122cdc20ff6SDimitry Andric }
1123cdc20ff6SDimitry Andric 
emitMCDCParameters(CGBuilderTy & Builder)1124cdc20ff6SDimitry Andric void CodeGenPGO::emitMCDCParameters(CGBuilderTy &Builder) {
1125cdc20ff6SDimitry Andric   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCBitmapMap)
1126cdc20ff6SDimitry Andric     return;
1127cdc20ff6SDimitry Andric 
1128cdc20ff6SDimitry Andric   auto *I8PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
1129cdc20ff6SDimitry Andric 
1130cdc20ff6SDimitry Andric   // Emit intrinsic representing MCDC bitmap parameters at function entry.
1131cdc20ff6SDimitry Andric   // This is used by the instrumentation pass, but it isn't actually lowered to
1132cdc20ff6SDimitry Andric   // anything.
1133cdc20ff6SDimitry Andric   llvm::Value *Args[3] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
1134cdc20ff6SDimitry Andric                           Builder.getInt64(FunctionHash),
1135cdc20ff6SDimitry Andric                           Builder.getInt32(MCDCBitmapBytes)};
1136cdc20ff6SDimitry Andric   Builder.CreateCall(
1137cdc20ff6SDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_parameters), Args);
1138cdc20ff6SDimitry Andric }
1139cdc20ff6SDimitry Andric 
emitMCDCTestVectorBitmapUpdate(CGBuilderTy & Builder,const Expr * S,Address MCDCCondBitmapAddr)1140cdc20ff6SDimitry Andric void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
1141cdc20ff6SDimitry Andric                                                 const Expr *S,
1142cdc20ff6SDimitry Andric                                                 Address MCDCCondBitmapAddr) {
1143cdc20ff6SDimitry Andric   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCBitmapMap)
1144cdc20ff6SDimitry Andric     return;
1145cdc20ff6SDimitry Andric 
1146cdc20ff6SDimitry Andric   S = S->IgnoreParens();
1147cdc20ff6SDimitry Andric 
1148cdc20ff6SDimitry Andric   auto ExprMCDCBitmapMapIterator = RegionMCDCBitmapMap->find(S);
1149cdc20ff6SDimitry Andric   if (ExprMCDCBitmapMapIterator == RegionMCDCBitmapMap->end())
1150cdc20ff6SDimitry Andric     return;
1151cdc20ff6SDimitry Andric 
1152cdc20ff6SDimitry Andric   // Extract the ID of the global bitmap associated with this expression.
1153cdc20ff6SDimitry Andric   unsigned MCDCTestVectorBitmapID = ExprMCDCBitmapMapIterator->second;
1154cdc20ff6SDimitry Andric   auto *I8PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
1155cdc20ff6SDimitry Andric 
1156cdc20ff6SDimitry Andric   // Emit intrinsic responsible for updating the global bitmap corresponding to
1157cdc20ff6SDimitry Andric   // a boolean expression. The index being set is based on the value loaded
1158cdc20ff6SDimitry Andric   // from a pointer to a dedicated temporary value on the stack that is itself
1159cdc20ff6SDimitry Andric   // updated via emitMCDCCondBitmapReset() and emitMCDCCondBitmapUpdate(). The
1160cdc20ff6SDimitry Andric   // index represents an executed test vector.
1161cdc20ff6SDimitry Andric   llvm::Value *Args[5] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
1162cdc20ff6SDimitry Andric                           Builder.getInt64(FunctionHash),
1163cdc20ff6SDimitry Andric                           Builder.getInt32(MCDCBitmapBytes),
1164cdc20ff6SDimitry Andric                           Builder.getInt32(MCDCTestVectorBitmapID),
1165cdc20ff6SDimitry Andric                           MCDCCondBitmapAddr.getPointer()};
1166cdc20ff6SDimitry Andric   Builder.CreateCall(
1167cdc20ff6SDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_tvbitmap_update), Args);
1168cdc20ff6SDimitry Andric }
1169cdc20ff6SDimitry Andric 
emitMCDCCondBitmapReset(CGBuilderTy & Builder,const Expr * S,Address MCDCCondBitmapAddr)1170cdc20ff6SDimitry Andric void CodeGenPGO::emitMCDCCondBitmapReset(CGBuilderTy &Builder, const Expr *S,
1171cdc20ff6SDimitry Andric                                          Address MCDCCondBitmapAddr) {
1172cdc20ff6SDimitry Andric   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCBitmapMap)
1173cdc20ff6SDimitry Andric     return;
1174cdc20ff6SDimitry Andric 
1175cdc20ff6SDimitry Andric   S = S->IgnoreParens();
1176cdc20ff6SDimitry Andric 
1177cdc20ff6SDimitry Andric   if (RegionMCDCBitmapMap->find(S) == RegionMCDCBitmapMap->end())
1178cdc20ff6SDimitry Andric     return;
1179cdc20ff6SDimitry Andric 
1180cdc20ff6SDimitry Andric   // Emit intrinsic that resets a dedicated temporary value on the stack to 0.
1181cdc20ff6SDimitry Andric   Builder.CreateStore(Builder.getInt32(0), MCDCCondBitmapAddr);
1182cdc20ff6SDimitry Andric }
1183cdc20ff6SDimitry Andric 
emitMCDCCondBitmapUpdate(CGBuilderTy & Builder,const Expr * S,Address MCDCCondBitmapAddr,llvm::Value * Val)1184cdc20ff6SDimitry Andric void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S,
1185cdc20ff6SDimitry Andric                                           Address MCDCCondBitmapAddr,
1186cdc20ff6SDimitry Andric                                           llvm::Value *Val) {
1187cdc20ff6SDimitry Andric   if (!canEmitMCDCCoverage(Builder) || !RegionCondIDMap)
1188cdc20ff6SDimitry Andric     return;
1189cdc20ff6SDimitry Andric 
1190cdc20ff6SDimitry Andric   // Even though, for simplicity, parentheses and unary logical-NOT operators
1191cdc20ff6SDimitry Andric   // are considered part of their underlying condition for both MC/DC and
1192cdc20ff6SDimitry Andric   // branch coverage, the condition IDs themselves are assigned and tracked
1193cdc20ff6SDimitry Andric   // using the underlying condition itself.  This is done solely for
1194cdc20ff6SDimitry Andric   // consistency since parentheses and logical-NOTs are ignored when checking
1195cdc20ff6SDimitry Andric   // whether the condition is actually an instrumentable condition. This can
1196cdc20ff6SDimitry Andric   // also make debugging a bit easier.
1197cdc20ff6SDimitry Andric   S = CodeGenFunction::stripCond(S);
1198cdc20ff6SDimitry Andric 
1199cdc20ff6SDimitry Andric   auto ExprMCDCConditionIDMapIterator = RegionCondIDMap->find(S);
1200cdc20ff6SDimitry Andric   if (ExprMCDCConditionIDMapIterator == RegionCondIDMap->end())
1201cdc20ff6SDimitry Andric     return;
1202cdc20ff6SDimitry Andric 
1203cdc20ff6SDimitry Andric   // Extract the ID of the condition we are setting in the bitmap.
1204cdc20ff6SDimitry Andric   unsigned CondID = ExprMCDCConditionIDMapIterator->second;
1205cdc20ff6SDimitry Andric   assert(CondID > 0 && "Condition has no ID!");
1206cdc20ff6SDimitry Andric 
1207cdc20ff6SDimitry Andric   auto *I8PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
1208cdc20ff6SDimitry Andric 
1209cdc20ff6SDimitry Andric   // Emit intrinsic that updates a dedicated temporary value on the stack after
1210cdc20ff6SDimitry Andric   // a condition is evaluated. After the set of conditions has been updated,
1211cdc20ff6SDimitry Andric   // the resulting value is used to update the boolean expression's bitmap.
1212cdc20ff6SDimitry Andric   llvm::Value *Args[5] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
1213cdc20ff6SDimitry Andric                           Builder.getInt64(FunctionHash),
1214cdc20ff6SDimitry Andric                           Builder.getInt32(CondID - 1),
1215cdc20ff6SDimitry Andric                           MCDCCondBitmapAddr.getPointer(), Val};
1216cdc20ff6SDimitry Andric   Builder.CreateCall(
1217cdc20ff6SDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_condbitmap_update),
1218cdc20ff6SDimitry Andric       Args);
1219cdc20ff6SDimitry Andric }
1220cdc20ff6SDimitry Andric 
setValueProfilingFlag(llvm::Module & M)1221fe6060f1SDimitry Andric void CodeGenPGO::setValueProfilingFlag(llvm::Module &M) {
1222fe6060f1SDimitry Andric   if (CGM.getCodeGenOpts().hasProfileClangInstr())
1223fe6060f1SDimitry Andric     M.addModuleFlag(llvm::Module::Warning, "EnableValueProfiling",
1224fe6060f1SDimitry Andric                     uint32_t(EnableValueProfiling));
1225fe6060f1SDimitry Andric }
1226fe6060f1SDimitry Andric 
12270b57cec5SDimitry Andric // This method either inserts a call to the profile run-time during
12280b57cec5SDimitry Andric // instrumentation or puts profile data into metadata for PGO use.
valueProfile(CGBuilderTy & Builder,uint32_t ValueKind,llvm::Instruction * ValueSite,llvm::Value * ValuePtr)12290b57cec5SDimitry Andric void CodeGenPGO::valueProfile(CGBuilderTy &Builder, uint32_t ValueKind,
12300b57cec5SDimitry Andric     llvm::Instruction *ValueSite, llvm::Value *ValuePtr) {
12310b57cec5SDimitry Andric 
12320b57cec5SDimitry Andric   if (!EnableValueProfiling)
12330b57cec5SDimitry Andric     return;
12340b57cec5SDimitry Andric 
12350b57cec5SDimitry Andric   if (!ValuePtr || !ValueSite || !Builder.GetInsertBlock())
12360b57cec5SDimitry Andric     return;
12370b57cec5SDimitry Andric 
12380b57cec5SDimitry Andric   if (isa<llvm::Constant>(ValuePtr))
12390b57cec5SDimitry Andric     return;
12400b57cec5SDimitry Andric 
12410b57cec5SDimitry Andric   bool InstrumentValueSites = CGM.getCodeGenOpts().hasProfileClangInstr();
12420b57cec5SDimitry Andric   if (InstrumentValueSites && RegionCounterMap) {
12430b57cec5SDimitry Andric     auto BuilderInsertPoint = Builder.saveIP();
12440b57cec5SDimitry Andric     Builder.SetInsertPoint(ValueSite);
12450b57cec5SDimitry Andric     llvm::Value *Args[5] = {
1246c9157d92SDimitry Andric         FuncNameVar,
12470b57cec5SDimitry Andric         Builder.getInt64(FunctionHash),
12480b57cec5SDimitry Andric         Builder.CreatePtrToInt(ValuePtr, Builder.getInt64Ty()),
12490b57cec5SDimitry Andric         Builder.getInt32(ValueKind),
12500b57cec5SDimitry Andric         Builder.getInt32(NumValueSites[ValueKind]++)
12510b57cec5SDimitry Andric     };
12520b57cec5SDimitry Andric     Builder.CreateCall(
12530b57cec5SDimitry Andric         CGM.getIntrinsic(llvm::Intrinsic::instrprof_value_profile), Args);
12540b57cec5SDimitry Andric     Builder.restoreIP(BuilderInsertPoint);
12550b57cec5SDimitry Andric     return;
12560b57cec5SDimitry Andric   }
12570b57cec5SDimitry Andric 
12580b57cec5SDimitry Andric   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
12590b57cec5SDimitry Andric   if (PGOReader && haveRegionCounts()) {
12600b57cec5SDimitry Andric     // We record the top most called three functions at each call site.
12610b57cec5SDimitry Andric     // Profile metadata contains "VP" string identifying this metadata
12620b57cec5SDimitry Andric     // as value profiling data, then a uint32_t value for the value profiling
12630b57cec5SDimitry Andric     // kind, a uint64_t value for the total number of times the call is
12640b57cec5SDimitry Andric     // executed, followed by the function hash and execution count (uint64_t)
12650b57cec5SDimitry Andric     // pairs for each function.
12660b57cec5SDimitry Andric     if (NumValueSites[ValueKind] >= ProfRecord->getNumValueSites(ValueKind))
12670b57cec5SDimitry Andric       return;
12680b57cec5SDimitry Andric 
12690b57cec5SDimitry Andric     llvm::annotateValueSite(CGM.getModule(), *ValueSite, *ProfRecord,
12700b57cec5SDimitry Andric                             (llvm::InstrProfValueKind)ValueKind,
12710b57cec5SDimitry Andric                             NumValueSites[ValueKind]);
12720b57cec5SDimitry Andric 
12730b57cec5SDimitry Andric     NumValueSites[ValueKind]++;
12740b57cec5SDimitry Andric   }
12750b57cec5SDimitry Andric }
12760b57cec5SDimitry Andric 
loadRegionCounts(llvm::IndexedInstrProfReader * PGOReader,bool IsInMainFile)12770b57cec5SDimitry Andric void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
12780b57cec5SDimitry Andric                                   bool IsInMainFile) {
12790b57cec5SDimitry Andric   CGM.getPGOStats().addVisited(IsInMainFile);
12800b57cec5SDimitry Andric   RegionCounts.clear();
12810b57cec5SDimitry Andric   llvm::Expected<llvm::InstrProfRecord> RecordExpected =
12820b57cec5SDimitry Andric       PGOReader->getInstrProfRecord(FuncName, FunctionHash);
12830b57cec5SDimitry Andric   if (auto E = RecordExpected.takeError()) {
1284fe013be4SDimitry Andric     auto IPE = std::get<0>(llvm::InstrProfError::take(std::move(E)));
12850b57cec5SDimitry Andric     if (IPE == llvm::instrprof_error::unknown_function)
12860b57cec5SDimitry Andric       CGM.getPGOStats().addMissing(IsInMainFile);
12870b57cec5SDimitry Andric     else if (IPE == llvm::instrprof_error::hash_mismatch)
12880b57cec5SDimitry Andric       CGM.getPGOStats().addMismatched(IsInMainFile);
12890b57cec5SDimitry Andric     else if (IPE == llvm::instrprof_error::malformed)
12900b57cec5SDimitry Andric       // TODO: Consider a more specific warning for this case.
12910b57cec5SDimitry Andric       CGM.getPGOStats().addMismatched(IsInMainFile);
12920b57cec5SDimitry Andric     return;
12930b57cec5SDimitry Andric   }
12940b57cec5SDimitry Andric   ProfRecord =
1295a7dea167SDimitry Andric       std::make_unique<llvm::InstrProfRecord>(std::move(RecordExpected.get()));
12960b57cec5SDimitry Andric   RegionCounts = ProfRecord->Counts;
12970b57cec5SDimitry Andric }
12980b57cec5SDimitry Andric 
12990b57cec5SDimitry Andric /// Calculate what to divide by to scale weights.
13000b57cec5SDimitry Andric ///
13010b57cec5SDimitry Andric /// Given the maximum weight, calculate a divisor that will scale all the
13020b57cec5SDimitry Andric /// weights to strictly less than UINT32_MAX.
calculateWeightScale(uint64_t MaxWeight)13030b57cec5SDimitry Andric static uint64_t calculateWeightScale(uint64_t MaxWeight) {
13040b57cec5SDimitry Andric   return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
13050b57cec5SDimitry Andric }
13060b57cec5SDimitry Andric 
13070b57cec5SDimitry Andric /// Scale an individual branch weight (and add 1).
13080b57cec5SDimitry Andric ///
13090b57cec5SDimitry Andric /// Scale a 64-bit weight down to 32-bits using \c Scale.
13100b57cec5SDimitry Andric ///
13110b57cec5SDimitry Andric /// According to Laplace's Rule of Succession, it is better to compute the
13120b57cec5SDimitry Andric /// weight based on the count plus 1, so universally add 1 to the value.
13130b57cec5SDimitry Andric ///
13140b57cec5SDimitry Andric /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
13150b57cec5SDimitry Andric /// greater than \c Weight.
scaleBranchWeight(uint64_t Weight,uint64_t Scale)13160b57cec5SDimitry Andric static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
13170b57cec5SDimitry Andric   assert(Scale && "scale by 0?");
13180b57cec5SDimitry Andric   uint64_t Scaled = Weight / Scale + 1;
13190b57cec5SDimitry Andric   assert(Scaled <= UINT32_MAX && "overflow 32-bits");
13200b57cec5SDimitry Andric   return Scaled;
13210b57cec5SDimitry Andric }
13220b57cec5SDimitry Andric 
createProfileWeights(uint64_t TrueCount,uint64_t FalseCount) const13230b57cec5SDimitry Andric llvm::MDNode *CodeGenFunction::createProfileWeights(uint64_t TrueCount,
1324e8d8bef9SDimitry Andric                                                     uint64_t FalseCount) const {
13250b57cec5SDimitry Andric   // Check for empty weights.
13260b57cec5SDimitry Andric   if (!TrueCount && !FalseCount)
13270b57cec5SDimitry Andric     return nullptr;
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric   // Calculate how to scale down to 32-bits.
13300b57cec5SDimitry Andric   uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
13310b57cec5SDimitry Andric 
13320b57cec5SDimitry Andric   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
13330b57cec5SDimitry Andric   return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
13340b57cec5SDimitry Andric                                       scaleBranchWeight(FalseCount, Scale));
13350b57cec5SDimitry Andric }
13360b57cec5SDimitry Andric 
13370b57cec5SDimitry Andric llvm::MDNode *
createProfileWeights(ArrayRef<uint64_t> Weights) const1338e8d8bef9SDimitry Andric CodeGenFunction::createProfileWeights(ArrayRef<uint64_t> Weights) const {
13390b57cec5SDimitry Andric   // We need at least two elements to create meaningful weights.
13400b57cec5SDimitry Andric   if (Weights.size() < 2)
13410b57cec5SDimitry Andric     return nullptr;
13420b57cec5SDimitry Andric 
13430b57cec5SDimitry Andric   // Check for empty weights.
13440b57cec5SDimitry Andric   uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
13450b57cec5SDimitry Andric   if (MaxWeight == 0)
13460b57cec5SDimitry Andric     return nullptr;
13470b57cec5SDimitry Andric 
13480b57cec5SDimitry Andric   // Calculate how to scale down to 32-bits.
13490b57cec5SDimitry Andric   uint64_t Scale = calculateWeightScale(MaxWeight);
13500b57cec5SDimitry Andric 
13510b57cec5SDimitry Andric   SmallVector<uint32_t, 16> ScaledWeights;
13520b57cec5SDimitry Andric   ScaledWeights.reserve(Weights.size());
13530b57cec5SDimitry Andric   for (uint64_t W : Weights)
13540b57cec5SDimitry Andric     ScaledWeights.push_back(scaleBranchWeight(W, Scale));
13550b57cec5SDimitry Andric 
13560b57cec5SDimitry Andric   llvm::MDBuilder MDHelper(CGM.getLLVMContext());
13570b57cec5SDimitry Andric   return MDHelper.createBranchWeights(ScaledWeights);
13580b57cec5SDimitry Andric }
13590b57cec5SDimitry Andric 
1360e8d8bef9SDimitry Andric llvm::MDNode *
createProfileWeightsForLoop(const Stmt * Cond,uint64_t LoopCount) const1361e8d8bef9SDimitry Andric CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond,
1362e8d8bef9SDimitry Andric                                              uint64_t LoopCount) const {
13630b57cec5SDimitry Andric   if (!PGO.haveRegionCounts())
13640b57cec5SDimitry Andric     return nullptr;
1365bdd1243dSDimitry Andric   std::optional<uint64_t> CondCount = PGO.getStmtCount(Cond);
13665ffd83dbSDimitry Andric   if (!CondCount || *CondCount == 0)
13670b57cec5SDimitry Andric     return nullptr;
13680b57cec5SDimitry Andric   return createProfileWeights(LoopCount,
13690b57cec5SDimitry Andric                               std::max(*CondCount, LoopCount) - LoopCount);
13700b57cec5SDimitry Andric }
1371