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