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