159d1ed5bSDimitry Andric //===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- C++ -*-===// 259d1ed5bSDimitry Andric // 359d1ed5bSDimitry Andric // The LLVM Compiler Infrastructure 459d1ed5bSDimitry Andric // 559d1ed5bSDimitry Andric // This file is distributed under the University of Illinois Open Source 659d1ed5bSDimitry Andric // License. See LICENSE.TXT for details. 759d1ed5bSDimitry Andric // 859d1ed5bSDimitry Andric //===----------------------------------------------------------------------===// 959d1ed5bSDimitry Andric // 1059d1ed5bSDimitry Andric // Instrumentation-based profile-guided optimization 1159d1ed5bSDimitry Andric // 1259d1ed5bSDimitry Andric //===----------------------------------------------------------------------===// 1359d1ed5bSDimitry Andric 1459d1ed5bSDimitry Andric #include "CodeGenPGO.h" 1559d1ed5bSDimitry Andric #include "CodeGenFunction.h" 1639d628a0SDimitry Andric #include "CoverageMappingGen.h" 1759d1ed5bSDimitry Andric #include "clang/AST/RecursiveASTVisitor.h" 1859d1ed5bSDimitry Andric #include "clang/AST/StmtVisitor.h" 1939d628a0SDimitry Andric #include "llvm/IR/Intrinsics.h" 2059d1ed5bSDimitry Andric #include "llvm/IR/MDBuilder.h" 2159d1ed5bSDimitry Andric #include "llvm/ProfileData/InstrProfReader.h" 2259d1ed5bSDimitry Andric #include "llvm/Support/Endian.h" 2359d1ed5bSDimitry Andric #include "llvm/Support/FileSystem.h" 2459d1ed5bSDimitry Andric #include "llvm/Support/MD5.h" 2559d1ed5bSDimitry Andric 2659d1ed5bSDimitry Andric using namespace clang; 2759d1ed5bSDimitry Andric using namespace CodeGen; 2859d1ed5bSDimitry Andric 2939d628a0SDimitry Andric void CodeGenPGO::setFuncName(StringRef Name, 3039d628a0SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage) { 3139d628a0SDimitry Andric StringRef RawFuncName = Name; 3259d1ed5bSDimitry Andric 3359d1ed5bSDimitry Andric // Function names may be prefixed with a binary '1' to indicate 3459d1ed5bSDimitry Andric // that the backend should not modify the symbols due to any platform 3559d1ed5bSDimitry Andric // naming convention. Do not include that '1' in the PGO profile name. 3659d1ed5bSDimitry Andric if (RawFuncName[0] == '\1') 3759d1ed5bSDimitry Andric RawFuncName = RawFuncName.substr(1); 3859d1ed5bSDimitry Andric 3939d628a0SDimitry Andric FuncName = RawFuncName; 4039d628a0SDimitry Andric if (llvm::GlobalValue::isLocalLinkage(Linkage)) { 4159d1ed5bSDimitry Andric // For local symbols, prepend the main file name to distinguish them. 4259d1ed5bSDimitry Andric // Do not include the full path in the file name since there's no guarantee 4359d1ed5bSDimitry Andric // that it will stay the same, e.g., if the files are checked out from 4459d1ed5bSDimitry Andric // version control in different locations. 4539d628a0SDimitry Andric if (CGM.getCodeGenOpts().MainFileName.empty()) 4639d628a0SDimitry Andric FuncName = FuncName.insert(0, "<unknown>:"); 4739d628a0SDimitry Andric else 4839d628a0SDimitry Andric FuncName = FuncName.insert(0, CGM.getCodeGenOpts().MainFileName + ":"); 4959d1ed5bSDimitry Andric } 5059d1ed5bSDimitry Andric 5139d628a0SDimitry Andric // If we're generating a profile, create a variable for the name. 5239d628a0SDimitry Andric if (CGM.getCodeGenOpts().ProfileInstrGenerate) 5339d628a0SDimitry Andric createFuncNameVar(Linkage); 5459d1ed5bSDimitry Andric } 5559d1ed5bSDimitry Andric 5639d628a0SDimitry Andric void CodeGenPGO::setFuncName(llvm::Function *Fn) { 5739d628a0SDimitry Andric setFuncName(Fn->getName(), Fn->getLinkage()); 5859d1ed5bSDimitry Andric } 5959d1ed5bSDimitry Andric 6039d628a0SDimitry Andric void CodeGenPGO::createFuncNameVar(llvm::GlobalValue::LinkageTypes Linkage) { 6139d628a0SDimitry Andric // Usually, we want to match the function's linkage, but 6239d628a0SDimitry Andric // available_externally and extern_weak both have the wrong semantics. 6339d628a0SDimitry Andric if (Linkage == llvm::GlobalValue::ExternalWeakLinkage) 6439d628a0SDimitry Andric Linkage = llvm::GlobalValue::LinkOnceAnyLinkage; 6539d628a0SDimitry Andric else if (Linkage == llvm::GlobalValue::AvailableExternallyLinkage) 6639d628a0SDimitry Andric Linkage = llvm::GlobalValue::LinkOnceODRLinkage; 6759d1ed5bSDimitry Andric 6839d628a0SDimitry Andric auto *Value = 6939d628a0SDimitry Andric llvm::ConstantDataArray::getString(CGM.getLLVMContext(), FuncName, false); 7039d628a0SDimitry Andric FuncNameVar = 7139d628a0SDimitry Andric new llvm::GlobalVariable(CGM.getModule(), Value->getType(), true, Linkage, 7239d628a0SDimitry Andric Value, "__llvm_profile_name_" + FuncName); 7359d1ed5bSDimitry Andric 7439d628a0SDimitry Andric // Hide the symbol so that we correctly get a copy for each executable. 7539d628a0SDimitry Andric if (!llvm::GlobalValue::isLocalLinkage(FuncNameVar->getLinkage())) 7639d628a0SDimitry Andric FuncNameVar->setVisibility(llvm::GlobalValue::HiddenVisibility); 7759d1ed5bSDimitry Andric } 7859d1ed5bSDimitry Andric 7959d1ed5bSDimitry Andric namespace { 8059d1ed5bSDimitry Andric /// \brief Stable hasher for PGO region counters. 8159d1ed5bSDimitry Andric /// 8259d1ed5bSDimitry Andric /// PGOHash produces a stable hash of a given function's control flow. 8359d1ed5bSDimitry Andric /// 8459d1ed5bSDimitry Andric /// Changing the output of this hash will invalidate all previously generated 8559d1ed5bSDimitry Andric /// profiles -- i.e., don't do it. 8659d1ed5bSDimitry Andric /// 8759d1ed5bSDimitry Andric /// \note When this hash does eventually change (years?), we still need to 8859d1ed5bSDimitry Andric /// support old hashes. We'll need to pull in the version number from the 8959d1ed5bSDimitry Andric /// profile data format and use the matching hash function. 9059d1ed5bSDimitry Andric class PGOHash { 9159d1ed5bSDimitry Andric uint64_t Working; 9259d1ed5bSDimitry Andric unsigned Count; 9359d1ed5bSDimitry Andric llvm::MD5 MD5; 9459d1ed5bSDimitry Andric 9559d1ed5bSDimitry Andric static const int NumBitsPerType = 6; 9659d1ed5bSDimitry Andric static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType; 9759d1ed5bSDimitry Andric static const unsigned TooBig = 1u << NumBitsPerType; 9859d1ed5bSDimitry Andric 9959d1ed5bSDimitry Andric public: 10059d1ed5bSDimitry Andric /// \brief Hash values for AST nodes. 10159d1ed5bSDimitry Andric /// 10259d1ed5bSDimitry Andric /// Distinct values for AST nodes that have region counters attached. 10359d1ed5bSDimitry Andric /// 10459d1ed5bSDimitry Andric /// These values must be stable. All new members must be added at the end, 10559d1ed5bSDimitry Andric /// and no members should be removed. Changing the enumeration value for an 10659d1ed5bSDimitry Andric /// AST node will affect the hash of every function that contains that node. 10759d1ed5bSDimitry Andric enum HashType : unsigned char { 10859d1ed5bSDimitry Andric None = 0, 10959d1ed5bSDimitry Andric LabelStmt = 1, 11059d1ed5bSDimitry Andric WhileStmt, 11159d1ed5bSDimitry Andric DoStmt, 11259d1ed5bSDimitry Andric ForStmt, 11359d1ed5bSDimitry Andric CXXForRangeStmt, 11459d1ed5bSDimitry Andric ObjCForCollectionStmt, 11559d1ed5bSDimitry Andric SwitchStmt, 11659d1ed5bSDimitry Andric CaseStmt, 11759d1ed5bSDimitry Andric DefaultStmt, 11859d1ed5bSDimitry Andric IfStmt, 11959d1ed5bSDimitry Andric CXXTryStmt, 12059d1ed5bSDimitry Andric CXXCatchStmt, 12159d1ed5bSDimitry Andric ConditionalOperator, 12259d1ed5bSDimitry Andric BinaryOperatorLAnd, 12359d1ed5bSDimitry Andric BinaryOperatorLOr, 12459d1ed5bSDimitry Andric BinaryConditionalOperator, 12559d1ed5bSDimitry Andric 12659d1ed5bSDimitry Andric // Keep this last. It's for the static assert that follows. 12759d1ed5bSDimitry Andric LastHashType 12859d1ed5bSDimitry Andric }; 12959d1ed5bSDimitry Andric static_assert(LastHashType <= TooBig, "Too many types in HashType"); 13059d1ed5bSDimitry Andric 13159d1ed5bSDimitry Andric // TODO: When this format changes, take in a version number here, and use the 13259d1ed5bSDimitry Andric // old hash calculation for file formats that used the old hash. 13359d1ed5bSDimitry Andric PGOHash() : Working(0), Count(0) {} 13459d1ed5bSDimitry Andric void combine(HashType Type); 13559d1ed5bSDimitry Andric uint64_t finalize(); 13659d1ed5bSDimitry Andric }; 13759d1ed5bSDimitry Andric const int PGOHash::NumBitsPerType; 13859d1ed5bSDimitry Andric const unsigned PGOHash::NumTypesPerWord; 13959d1ed5bSDimitry Andric const unsigned PGOHash::TooBig; 14059d1ed5bSDimitry Andric 14159d1ed5bSDimitry Andric /// A RecursiveASTVisitor that fills a map of statements to PGO counters. 14259d1ed5bSDimitry Andric struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> { 14359d1ed5bSDimitry Andric /// The next counter value to assign. 14459d1ed5bSDimitry Andric unsigned NextCounter; 14559d1ed5bSDimitry Andric /// The function hash. 14659d1ed5bSDimitry Andric PGOHash Hash; 14759d1ed5bSDimitry Andric /// The map of statements to counters. 14859d1ed5bSDimitry Andric llvm::DenseMap<const Stmt *, unsigned> &CounterMap; 14959d1ed5bSDimitry Andric 15059d1ed5bSDimitry Andric MapRegionCounters(llvm::DenseMap<const Stmt *, unsigned> &CounterMap) 15159d1ed5bSDimitry Andric : NextCounter(0), CounterMap(CounterMap) {} 15259d1ed5bSDimitry Andric 15359d1ed5bSDimitry Andric // Blocks and lambdas are handled as separate functions, so we need not 15459d1ed5bSDimitry Andric // traverse them in the parent context. 15559d1ed5bSDimitry Andric bool TraverseBlockExpr(BlockExpr *BE) { return true; } 15659d1ed5bSDimitry Andric bool TraverseLambdaBody(LambdaExpr *LE) { return true; } 15759d1ed5bSDimitry Andric bool TraverseCapturedStmt(CapturedStmt *CS) { return true; } 15859d1ed5bSDimitry Andric 15959d1ed5bSDimitry Andric bool VisitDecl(const Decl *D) { 16059d1ed5bSDimitry Andric switch (D->getKind()) { 16159d1ed5bSDimitry Andric default: 16259d1ed5bSDimitry Andric break; 16359d1ed5bSDimitry Andric case Decl::Function: 16459d1ed5bSDimitry Andric case Decl::CXXMethod: 16559d1ed5bSDimitry Andric case Decl::CXXConstructor: 16659d1ed5bSDimitry Andric case Decl::CXXDestructor: 16759d1ed5bSDimitry Andric case Decl::CXXConversion: 16859d1ed5bSDimitry Andric case Decl::ObjCMethod: 16959d1ed5bSDimitry Andric case Decl::Block: 17059d1ed5bSDimitry Andric case Decl::Captured: 17159d1ed5bSDimitry Andric CounterMap[D->getBody()] = NextCounter++; 17259d1ed5bSDimitry Andric break; 17359d1ed5bSDimitry Andric } 17459d1ed5bSDimitry Andric return true; 17559d1ed5bSDimitry Andric } 17659d1ed5bSDimitry Andric 17759d1ed5bSDimitry Andric bool VisitStmt(const Stmt *S) { 17859d1ed5bSDimitry Andric auto Type = getHashType(S); 17959d1ed5bSDimitry Andric if (Type == PGOHash::None) 18059d1ed5bSDimitry Andric return true; 18159d1ed5bSDimitry Andric 18259d1ed5bSDimitry Andric CounterMap[S] = NextCounter++; 18359d1ed5bSDimitry Andric Hash.combine(Type); 18459d1ed5bSDimitry Andric return true; 18559d1ed5bSDimitry Andric } 18659d1ed5bSDimitry Andric PGOHash::HashType getHashType(const Stmt *S) { 18759d1ed5bSDimitry Andric switch (S->getStmtClass()) { 18859d1ed5bSDimitry Andric default: 18959d1ed5bSDimitry Andric break; 19059d1ed5bSDimitry Andric case Stmt::LabelStmtClass: 19159d1ed5bSDimitry Andric return PGOHash::LabelStmt; 19259d1ed5bSDimitry Andric case Stmt::WhileStmtClass: 19359d1ed5bSDimitry Andric return PGOHash::WhileStmt; 19459d1ed5bSDimitry Andric case Stmt::DoStmtClass: 19559d1ed5bSDimitry Andric return PGOHash::DoStmt; 19659d1ed5bSDimitry Andric case Stmt::ForStmtClass: 19759d1ed5bSDimitry Andric return PGOHash::ForStmt; 19859d1ed5bSDimitry Andric case Stmt::CXXForRangeStmtClass: 19959d1ed5bSDimitry Andric return PGOHash::CXXForRangeStmt; 20059d1ed5bSDimitry Andric case Stmt::ObjCForCollectionStmtClass: 20159d1ed5bSDimitry Andric return PGOHash::ObjCForCollectionStmt; 20259d1ed5bSDimitry Andric case Stmt::SwitchStmtClass: 20359d1ed5bSDimitry Andric return PGOHash::SwitchStmt; 20459d1ed5bSDimitry Andric case Stmt::CaseStmtClass: 20559d1ed5bSDimitry Andric return PGOHash::CaseStmt; 20659d1ed5bSDimitry Andric case Stmt::DefaultStmtClass: 20759d1ed5bSDimitry Andric return PGOHash::DefaultStmt; 20859d1ed5bSDimitry Andric case Stmt::IfStmtClass: 20959d1ed5bSDimitry Andric return PGOHash::IfStmt; 21059d1ed5bSDimitry Andric case Stmt::CXXTryStmtClass: 21159d1ed5bSDimitry Andric return PGOHash::CXXTryStmt; 21259d1ed5bSDimitry Andric case Stmt::CXXCatchStmtClass: 21359d1ed5bSDimitry Andric return PGOHash::CXXCatchStmt; 21459d1ed5bSDimitry Andric case Stmt::ConditionalOperatorClass: 21559d1ed5bSDimitry Andric return PGOHash::ConditionalOperator; 21659d1ed5bSDimitry Andric case Stmt::BinaryConditionalOperatorClass: 21759d1ed5bSDimitry Andric return PGOHash::BinaryConditionalOperator; 21859d1ed5bSDimitry Andric case Stmt::BinaryOperatorClass: { 21959d1ed5bSDimitry Andric const BinaryOperator *BO = cast<BinaryOperator>(S); 22059d1ed5bSDimitry Andric if (BO->getOpcode() == BO_LAnd) 22159d1ed5bSDimitry Andric return PGOHash::BinaryOperatorLAnd; 22259d1ed5bSDimitry Andric if (BO->getOpcode() == BO_LOr) 22359d1ed5bSDimitry Andric return PGOHash::BinaryOperatorLOr; 22459d1ed5bSDimitry Andric break; 22559d1ed5bSDimitry Andric } 22659d1ed5bSDimitry Andric } 22759d1ed5bSDimitry Andric return PGOHash::None; 22859d1ed5bSDimitry Andric } 22959d1ed5bSDimitry Andric }; 23059d1ed5bSDimitry Andric 23159d1ed5bSDimitry Andric /// A StmtVisitor that propagates the raw counts through the AST and 23259d1ed5bSDimitry Andric /// records the count at statements where the value may change. 23359d1ed5bSDimitry Andric struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> { 23459d1ed5bSDimitry Andric /// PGO state. 23559d1ed5bSDimitry Andric CodeGenPGO &PGO; 23659d1ed5bSDimitry Andric 23759d1ed5bSDimitry Andric /// A flag that is set when the current count should be recorded on the 23859d1ed5bSDimitry Andric /// next statement, such as at the exit of a loop. 23959d1ed5bSDimitry Andric bool RecordNextStmtCount; 24059d1ed5bSDimitry Andric 24159d1ed5bSDimitry Andric /// The map of statements to count values. 24259d1ed5bSDimitry Andric llvm::DenseMap<const Stmt *, uint64_t> &CountMap; 24359d1ed5bSDimitry Andric 24459d1ed5bSDimitry Andric /// BreakContinueStack - Keep counts of breaks and continues inside loops. 24559d1ed5bSDimitry Andric struct BreakContinue { 24659d1ed5bSDimitry Andric uint64_t BreakCount; 24759d1ed5bSDimitry Andric uint64_t ContinueCount; 24859d1ed5bSDimitry Andric BreakContinue() : BreakCount(0), ContinueCount(0) {} 24959d1ed5bSDimitry Andric }; 25059d1ed5bSDimitry Andric SmallVector<BreakContinue, 8> BreakContinueStack; 25159d1ed5bSDimitry Andric 25259d1ed5bSDimitry Andric ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap, 25359d1ed5bSDimitry Andric CodeGenPGO &PGO) 25459d1ed5bSDimitry Andric : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {} 25559d1ed5bSDimitry Andric 25659d1ed5bSDimitry Andric void RecordStmtCount(const Stmt *S) { 25759d1ed5bSDimitry Andric if (RecordNextStmtCount) { 25859d1ed5bSDimitry Andric CountMap[S] = PGO.getCurrentRegionCount(); 25959d1ed5bSDimitry Andric RecordNextStmtCount = false; 26059d1ed5bSDimitry Andric } 26159d1ed5bSDimitry Andric } 26259d1ed5bSDimitry Andric 26359d1ed5bSDimitry Andric void VisitStmt(const Stmt *S) { 26459d1ed5bSDimitry Andric RecordStmtCount(S); 26559d1ed5bSDimitry Andric for (Stmt::const_child_range I = S->children(); I; ++I) { 26659d1ed5bSDimitry Andric if (*I) 26759d1ed5bSDimitry Andric this->Visit(*I); 26859d1ed5bSDimitry Andric } 26959d1ed5bSDimitry Andric } 27059d1ed5bSDimitry Andric 27159d1ed5bSDimitry Andric void VisitFunctionDecl(const FunctionDecl *D) { 27259d1ed5bSDimitry Andric // Counter tracks entry to the function body. 27359d1ed5bSDimitry Andric RegionCounter Cnt(PGO, D->getBody()); 27459d1ed5bSDimitry Andric Cnt.beginRegion(); 27559d1ed5bSDimitry Andric CountMap[D->getBody()] = PGO.getCurrentRegionCount(); 27659d1ed5bSDimitry Andric Visit(D->getBody()); 27759d1ed5bSDimitry Andric } 27859d1ed5bSDimitry Andric 27959d1ed5bSDimitry Andric // Skip lambda expressions. We visit these as FunctionDecls when we're 28059d1ed5bSDimitry Andric // generating them and aren't interested in the body when generating a 28159d1ed5bSDimitry Andric // parent context. 28259d1ed5bSDimitry Andric void VisitLambdaExpr(const LambdaExpr *LE) {} 28359d1ed5bSDimitry Andric 28459d1ed5bSDimitry Andric void VisitCapturedDecl(const CapturedDecl *D) { 28559d1ed5bSDimitry Andric // Counter tracks entry to the capture body. 28659d1ed5bSDimitry Andric RegionCounter Cnt(PGO, D->getBody()); 28759d1ed5bSDimitry Andric Cnt.beginRegion(); 28859d1ed5bSDimitry Andric CountMap[D->getBody()] = PGO.getCurrentRegionCount(); 28959d1ed5bSDimitry Andric Visit(D->getBody()); 29059d1ed5bSDimitry Andric } 29159d1ed5bSDimitry Andric 29259d1ed5bSDimitry Andric void VisitObjCMethodDecl(const ObjCMethodDecl *D) { 29359d1ed5bSDimitry Andric // Counter tracks entry to the method body. 29459d1ed5bSDimitry Andric RegionCounter Cnt(PGO, D->getBody()); 29559d1ed5bSDimitry Andric Cnt.beginRegion(); 29659d1ed5bSDimitry Andric CountMap[D->getBody()] = PGO.getCurrentRegionCount(); 29759d1ed5bSDimitry Andric Visit(D->getBody()); 29859d1ed5bSDimitry Andric } 29959d1ed5bSDimitry Andric 30059d1ed5bSDimitry Andric void VisitBlockDecl(const BlockDecl *D) { 30159d1ed5bSDimitry Andric // Counter tracks entry to the block body. 30259d1ed5bSDimitry Andric RegionCounter Cnt(PGO, D->getBody()); 30359d1ed5bSDimitry Andric Cnt.beginRegion(); 30459d1ed5bSDimitry Andric CountMap[D->getBody()] = PGO.getCurrentRegionCount(); 30559d1ed5bSDimitry Andric Visit(D->getBody()); 30659d1ed5bSDimitry Andric } 30759d1ed5bSDimitry Andric 30859d1ed5bSDimitry Andric void VisitReturnStmt(const ReturnStmt *S) { 30959d1ed5bSDimitry Andric RecordStmtCount(S); 31059d1ed5bSDimitry Andric if (S->getRetValue()) 31159d1ed5bSDimitry Andric Visit(S->getRetValue()); 31259d1ed5bSDimitry Andric PGO.setCurrentRegionUnreachable(); 31359d1ed5bSDimitry Andric RecordNextStmtCount = true; 31459d1ed5bSDimitry Andric } 31559d1ed5bSDimitry Andric 31659d1ed5bSDimitry Andric void VisitGotoStmt(const GotoStmt *S) { 31759d1ed5bSDimitry Andric RecordStmtCount(S); 31859d1ed5bSDimitry Andric PGO.setCurrentRegionUnreachable(); 31959d1ed5bSDimitry Andric RecordNextStmtCount = true; 32059d1ed5bSDimitry Andric } 32159d1ed5bSDimitry Andric 32259d1ed5bSDimitry Andric void VisitLabelStmt(const LabelStmt *S) { 32359d1ed5bSDimitry Andric RecordNextStmtCount = false; 32459d1ed5bSDimitry Andric // Counter tracks the block following the label. 32559d1ed5bSDimitry Andric RegionCounter Cnt(PGO, S); 32659d1ed5bSDimitry Andric Cnt.beginRegion(); 32759d1ed5bSDimitry Andric CountMap[S] = PGO.getCurrentRegionCount(); 32859d1ed5bSDimitry Andric Visit(S->getSubStmt()); 32959d1ed5bSDimitry Andric } 33059d1ed5bSDimitry Andric 33159d1ed5bSDimitry Andric void VisitBreakStmt(const BreakStmt *S) { 33259d1ed5bSDimitry Andric RecordStmtCount(S); 33359d1ed5bSDimitry Andric assert(!BreakContinueStack.empty() && "break not in a loop or switch!"); 33459d1ed5bSDimitry Andric BreakContinueStack.back().BreakCount += PGO.getCurrentRegionCount(); 33559d1ed5bSDimitry Andric PGO.setCurrentRegionUnreachable(); 33659d1ed5bSDimitry Andric RecordNextStmtCount = true; 33759d1ed5bSDimitry Andric } 33859d1ed5bSDimitry Andric 33959d1ed5bSDimitry Andric void VisitContinueStmt(const ContinueStmt *S) { 34059d1ed5bSDimitry Andric RecordStmtCount(S); 34159d1ed5bSDimitry Andric assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 34259d1ed5bSDimitry Andric BreakContinueStack.back().ContinueCount += PGO.getCurrentRegionCount(); 34359d1ed5bSDimitry Andric PGO.setCurrentRegionUnreachable(); 34459d1ed5bSDimitry Andric RecordNextStmtCount = true; 34559d1ed5bSDimitry Andric } 34659d1ed5bSDimitry Andric 34759d1ed5bSDimitry Andric void VisitWhileStmt(const WhileStmt *S) { 34859d1ed5bSDimitry Andric RecordStmtCount(S); 34959d1ed5bSDimitry Andric // Counter tracks the body of the loop. 35059d1ed5bSDimitry Andric RegionCounter Cnt(PGO, S); 35159d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 35259d1ed5bSDimitry Andric // Visit the body region first so the break/continue adjustments can be 35359d1ed5bSDimitry Andric // included when visiting the condition. 35459d1ed5bSDimitry Andric Cnt.beginRegion(); 35559d1ed5bSDimitry Andric CountMap[S->getBody()] = PGO.getCurrentRegionCount(); 35659d1ed5bSDimitry Andric Visit(S->getBody()); 35759d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 35859d1ed5bSDimitry Andric 35959d1ed5bSDimitry Andric // ...then go back and propagate counts through the condition. The count 36059d1ed5bSDimitry Andric // at the start of the condition is the sum of the incoming edges, 36159d1ed5bSDimitry Andric // the backedge from the end of the loop body, and the edges from 36259d1ed5bSDimitry Andric // continue statements. 36359d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 36459d1ed5bSDimitry Andric Cnt.setCurrentRegionCount(Cnt.getParentCount() + 36559d1ed5bSDimitry Andric Cnt.getAdjustedCount() + BC.ContinueCount); 36659d1ed5bSDimitry Andric CountMap[S->getCond()] = PGO.getCurrentRegionCount(); 36759d1ed5bSDimitry Andric Visit(S->getCond()); 36859d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 36959d1ed5bSDimitry Andric Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount); 37059d1ed5bSDimitry Andric RecordNextStmtCount = true; 37159d1ed5bSDimitry Andric } 37259d1ed5bSDimitry Andric 37359d1ed5bSDimitry Andric void VisitDoStmt(const DoStmt *S) { 37459d1ed5bSDimitry Andric RecordStmtCount(S); 37559d1ed5bSDimitry Andric // Counter tracks the body of the loop. 37659d1ed5bSDimitry Andric RegionCounter Cnt(PGO, S); 37759d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 37859d1ed5bSDimitry Andric Cnt.beginRegion(/*AddIncomingFallThrough=*/true); 37959d1ed5bSDimitry Andric CountMap[S->getBody()] = PGO.getCurrentRegionCount(); 38059d1ed5bSDimitry Andric Visit(S->getBody()); 38159d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 38259d1ed5bSDimitry Andric 38359d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 38459d1ed5bSDimitry Andric // The count at the start of the condition is equal to the count at the 38559d1ed5bSDimitry Andric // end of the body. The adjusted count does not include either the 38659d1ed5bSDimitry Andric // fall-through count coming into the loop or the continue count, so add 38759d1ed5bSDimitry Andric // both of those separately. This is coincidentally the same equation as 38859d1ed5bSDimitry Andric // with while loops but for different reasons. 38959d1ed5bSDimitry Andric Cnt.setCurrentRegionCount(Cnt.getParentCount() + 39059d1ed5bSDimitry Andric Cnt.getAdjustedCount() + BC.ContinueCount); 39159d1ed5bSDimitry Andric CountMap[S->getCond()] = PGO.getCurrentRegionCount(); 39259d1ed5bSDimitry Andric Visit(S->getCond()); 39359d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 39459d1ed5bSDimitry Andric Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount); 39559d1ed5bSDimitry Andric RecordNextStmtCount = true; 39659d1ed5bSDimitry Andric } 39759d1ed5bSDimitry Andric 39859d1ed5bSDimitry Andric void VisitForStmt(const ForStmt *S) { 39959d1ed5bSDimitry Andric RecordStmtCount(S); 40059d1ed5bSDimitry Andric if (S->getInit()) 40159d1ed5bSDimitry Andric Visit(S->getInit()); 40259d1ed5bSDimitry Andric // Counter tracks the body of the loop. 40359d1ed5bSDimitry Andric RegionCounter Cnt(PGO, S); 40459d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 40559d1ed5bSDimitry Andric // Visit the body region first. (This is basically the same as a while 40659d1ed5bSDimitry Andric // loop; see further comments in VisitWhileStmt.) 40759d1ed5bSDimitry Andric Cnt.beginRegion(); 40859d1ed5bSDimitry Andric CountMap[S->getBody()] = PGO.getCurrentRegionCount(); 40959d1ed5bSDimitry Andric Visit(S->getBody()); 41059d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 41159d1ed5bSDimitry Andric 41259d1ed5bSDimitry Andric // The increment is essentially part of the body but it needs to include 41359d1ed5bSDimitry Andric // the count for all the continue statements. 41459d1ed5bSDimitry Andric if (S->getInc()) { 41559d1ed5bSDimitry Andric Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() + 41659d1ed5bSDimitry Andric BreakContinueStack.back().ContinueCount); 41759d1ed5bSDimitry Andric CountMap[S->getInc()] = PGO.getCurrentRegionCount(); 41859d1ed5bSDimitry Andric Visit(S->getInc()); 41959d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 42059d1ed5bSDimitry Andric } 42159d1ed5bSDimitry Andric 42259d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 42359d1ed5bSDimitry Andric 42459d1ed5bSDimitry Andric // ...then go back and propagate counts through the condition. 42559d1ed5bSDimitry Andric if (S->getCond()) { 42659d1ed5bSDimitry Andric Cnt.setCurrentRegionCount(Cnt.getParentCount() + 42759d1ed5bSDimitry Andric Cnt.getAdjustedCount() + 42859d1ed5bSDimitry Andric BC.ContinueCount); 42959d1ed5bSDimitry Andric CountMap[S->getCond()] = PGO.getCurrentRegionCount(); 43059d1ed5bSDimitry Andric Visit(S->getCond()); 43159d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 43259d1ed5bSDimitry Andric } 43359d1ed5bSDimitry Andric Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount); 43459d1ed5bSDimitry Andric RecordNextStmtCount = true; 43559d1ed5bSDimitry Andric } 43659d1ed5bSDimitry Andric 43759d1ed5bSDimitry Andric void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { 43859d1ed5bSDimitry Andric RecordStmtCount(S); 43959d1ed5bSDimitry Andric Visit(S->getRangeStmt()); 44059d1ed5bSDimitry Andric Visit(S->getBeginEndStmt()); 44159d1ed5bSDimitry Andric // Counter tracks the body of the loop. 44259d1ed5bSDimitry Andric RegionCounter Cnt(PGO, S); 44359d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 44459d1ed5bSDimitry Andric // Visit the body region first. (This is basically the same as a while 44559d1ed5bSDimitry Andric // loop; see further comments in VisitWhileStmt.) 44659d1ed5bSDimitry Andric Cnt.beginRegion(); 44759d1ed5bSDimitry Andric CountMap[S->getLoopVarStmt()] = PGO.getCurrentRegionCount(); 44859d1ed5bSDimitry Andric Visit(S->getLoopVarStmt()); 44959d1ed5bSDimitry Andric Visit(S->getBody()); 45059d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 45159d1ed5bSDimitry Andric 45259d1ed5bSDimitry Andric // The increment is essentially part of the body but it needs to include 45359d1ed5bSDimitry Andric // the count for all the continue statements. 45459d1ed5bSDimitry Andric Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() + 45559d1ed5bSDimitry Andric BreakContinueStack.back().ContinueCount); 45659d1ed5bSDimitry Andric CountMap[S->getInc()] = PGO.getCurrentRegionCount(); 45759d1ed5bSDimitry Andric Visit(S->getInc()); 45859d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 45959d1ed5bSDimitry Andric 46059d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 46159d1ed5bSDimitry Andric 46259d1ed5bSDimitry Andric // ...then go back and propagate counts through the condition. 46359d1ed5bSDimitry Andric Cnt.setCurrentRegionCount(Cnt.getParentCount() + 46459d1ed5bSDimitry Andric Cnt.getAdjustedCount() + 46559d1ed5bSDimitry Andric BC.ContinueCount); 46659d1ed5bSDimitry Andric CountMap[S->getCond()] = PGO.getCurrentRegionCount(); 46759d1ed5bSDimitry Andric Visit(S->getCond()); 46859d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 46959d1ed5bSDimitry Andric Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount); 47059d1ed5bSDimitry Andric RecordNextStmtCount = true; 47159d1ed5bSDimitry Andric } 47259d1ed5bSDimitry Andric 47359d1ed5bSDimitry Andric void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { 47459d1ed5bSDimitry Andric RecordStmtCount(S); 47559d1ed5bSDimitry Andric Visit(S->getElement()); 47659d1ed5bSDimitry Andric // Counter tracks the body of the loop. 47759d1ed5bSDimitry Andric RegionCounter Cnt(PGO, S); 47859d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 47959d1ed5bSDimitry Andric Cnt.beginRegion(); 48059d1ed5bSDimitry Andric CountMap[S->getBody()] = PGO.getCurrentRegionCount(); 48159d1ed5bSDimitry Andric Visit(S->getBody()); 48259d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 48359d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 48459d1ed5bSDimitry Andric Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount); 48559d1ed5bSDimitry Andric RecordNextStmtCount = true; 48659d1ed5bSDimitry Andric } 48759d1ed5bSDimitry Andric 48859d1ed5bSDimitry Andric void VisitSwitchStmt(const SwitchStmt *S) { 48959d1ed5bSDimitry Andric RecordStmtCount(S); 49059d1ed5bSDimitry Andric Visit(S->getCond()); 49159d1ed5bSDimitry Andric PGO.setCurrentRegionUnreachable(); 49259d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 49359d1ed5bSDimitry Andric Visit(S->getBody()); 49459d1ed5bSDimitry Andric // If the switch is inside a loop, add the continue counts. 49559d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 49659d1ed5bSDimitry Andric if (!BreakContinueStack.empty()) 49759d1ed5bSDimitry Andric BreakContinueStack.back().ContinueCount += BC.ContinueCount; 49859d1ed5bSDimitry Andric // Counter tracks the exit block of the switch. 49959d1ed5bSDimitry Andric RegionCounter ExitCnt(PGO, S); 50059d1ed5bSDimitry Andric ExitCnt.beginRegion(); 50159d1ed5bSDimitry Andric RecordNextStmtCount = true; 50259d1ed5bSDimitry Andric } 50359d1ed5bSDimitry Andric 50459d1ed5bSDimitry Andric void VisitCaseStmt(const CaseStmt *S) { 50559d1ed5bSDimitry Andric RecordNextStmtCount = false; 50659d1ed5bSDimitry Andric // Counter for this particular case. This counts only jumps from the 50759d1ed5bSDimitry Andric // switch header and does not include fallthrough from the case before 50859d1ed5bSDimitry Andric // this one. 50959d1ed5bSDimitry Andric RegionCounter Cnt(PGO, S); 51059d1ed5bSDimitry Andric Cnt.beginRegion(/*AddIncomingFallThrough=*/true); 51159d1ed5bSDimitry Andric CountMap[S] = Cnt.getCount(); 51259d1ed5bSDimitry Andric RecordNextStmtCount = true; 51359d1ed5bSDimitry Andric Visit(S->getSubStmt()); 51459d1ed5bSDimitry Andric } 51559d1ed5bSDimitry Andric 51659d1ed5bSDimitry Andric void VisitDefaultStmt(const DefaultStmt *S) { 51759d1ed5bSDimitry Andric RecordNextStmtCount = false; 51859d1ed5bSDimitry Andric // Counter for this default case. This does not include fallthrough from 51959d1ed5bSDimitry Andric // the previous case. 52059d1ed5bSDimitry Andric RegionCounter Cnt(PGO, S); 52159d1ed5bSDimitry Andric Cnt.beginRegion(/*AddIncomingFallThrough=*/true); 52259d1ed5bSDimitry Andric CountMap[S] = Cnt.getCount(); 52359d1ed5bSDimitry Andric RecordNextStmtCount = true; 52459d1ed5bSDimitry Andric Visit(S->getSubStmt()); 52559d1ed5bSDimitry Andric } 52659d1ed5bSDimitry Andric 52759d1ed5bSDimitry Andric void VisitIfStmt(const IfStmt *S) { 52859d1ed5bSDimitry Andric RecordStmtCount(S); 52959d1ed5bSDimitry Andric // Counter tracks the "then" part of an if statement. The count for 53059d1ed5bSDimitry Andric // the "else" part, if it exists, will be calculated from this counter. 53159d1ed5bSDimitry Andric RegionCounter Cnt(PGO, S); 53259d1ed5bSDimitry Andric Visit(S->getCond()); 53359d1ed5bSDimitry Andric 53459d1ed5bSDimitry Andric Cnt.beginRegion(); 53559d1ed5bSDimitry Andric CountMap[S->getThen()] = PGO.getCurrentRegionCount(); 53659d1ed5bSDimitry Andric Visit(S->getThen()); 53759d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 53859d1ed5bSDimitry Andric 53959d1ed5bSDimitry Andric if (S->getElse()) { 54059d1ed5bSDimitry Andric Cnt.beginElseRegion(); 54159d1ed5bSDimitry Andric CountMap[S->getElse()] = PGO.getCurrentRegionCount(); 54259d1ed5bSDimitry Andric Visit(S->getElse()); 54359d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 54459d1ed5bSDimitry Andric } 54559d1ed5bSDimitry Andric Cnt.applyAdjustmentsToRegion(0); 54659d1ed5bSDimitry Andric RecordNextStmtCount = true; 54759d1ed5bSDimitry Andric } 54859d1ed5bSDimitry Andric 54959d1ed5bSDimitry Andric void VisitCXXTryStmt(const CXXTryStmt *S) { 55059d1ed5bSDimitry Andric RecordStmtCount(S); 55159d1ed5bSDimitry Andric Visit(S->getTryBlock()); 55259d1ed5bSDimitry Andric for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I) 55359d1ed5bSDimitry Andric Visit(S->getHandler(I)); 55459d1ed5bSDimitry Andric // Counter tracks the continuation block of the try statement. 55559d1ed5bSDimitry Andric RegionCounter Cnt(PGO, S); 55659d1ed5bSDimitry Andric Cnt.beginRegion(); 55759d1ed5bSDimitry Andric RecordNextStmtCount = true; 55859d1ed5bSDimitry Andric } 55959d1ed5bSDimitry Andric 56059d1ed5bSDimitry Andric void VisitCXXCatchStmt(const CXXCatchStmt *S) { 56159d1ed5bSDimitry Andric RecordNextStmtCount = false; 56259d1ed5bSDimitry Andric // Counter tracks the catch statement's handler block. 56359d1ed5bSDimitry Andric RegionCounter Cnt(PGO, S); 56459d1ed5bSDimitry Andric Cnt.beginRegion(); 56559d1ed5bSDimitry Andric CountMap[S] = PGO.getCurrentRegionCount(); 56659d1ed5bSDimitry Andric Visit(S->getHandlerBlock()); 56759d1ed5bSDimitry Andric } 56859d1ed5bSDimitry Andric 56959d1ed5bSDimitry Andric void VisitAbstractConditionalOperator( 57059d1ed5bSDimitry Andric const AbstractConditionalOperator *E) { 57159d1ed5bSDimitry Andric RecordStmtCount(E); 57259d1ed5bSDimitry Andric // Counter tracks the "true" part of a conditional operator. The 57359d1ed5bSDimitry Andric // count in the "false" part will be calculated from this counter. 57459d1ed5bSDimitry Andric RegionCounter Cnt(PGO, E); 57559d1ed5bSDimitry Andric Visit(E->getCond()); 57659d1ed5bSDimitry Andric 57759d1ed5bSDimitry Andric Cnt.beginRegion(); 57859d1ed5bSDimitry Andric CountMap[E->getTrueExpr()] = PGO.getCurrentRegionCount(); 57959d1ed5bSDimitry Andric Visit(E->getTrueExpr()); 58059d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 58159d1ed5bSDimitry Andric 58259d1ed5bSDimitry Andric Cnt.beginElseRegion(); 58359d1ed5bSDimitry Andric CountMap[E->getFalseExpr()] = PGO.getCurrentRegionCount(); 58459d1ed5bSDimitry Andric Visit(E->getFalseExpr()); 58559d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 58659d1ed5bSDimitry Andric 58759d1ed5bSDimitry Andric Cnt.applyAdjustmentsToRegion(0); 58859d1ed5bSDimitry Andric RecordNextStmtCount = true; 58959d1ed5bSDimitry Andric } 59059d1ed5bSDimitry Andric 59159d1ed5bSDimitry Andric void VisitBinLAnd(const BinaryOperator *E) { 59259d1ed5bSDimitry Andric RecordStmtCount(E); 59359d1ed5bSDimitry Andric // Counter tracks the right hand side of a logical and operator. 59459d1ed5bSDimitry Andric RegionCounter Cnt(PGO, E); 59559d1ed5bSDimitry Andric Visit(E->getLHS()); 59659d1ed5bSDimitry Andric Cnt.beginRegion(); 59759d1ed5bSDimitry Andric CountMap[E->getRHS()] = PGO.getCurrentRegionCount(); 59859d1ed5bSDimitry Andric Visit(E->getRHS()); 59959d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 60059d1ed5bSDimitry Andric Cnt.applyAdjustmentsToRegion(0); 60159d1ed5bSDimitry Andric RecordNextStmtCount = true; 60259d1ed5bSDimitry Andric } 60359d1ed5bSDimitry Andric 60459d1ed5bSDimitry Andric void VisitBinLOr(const BinaryOperator *E) { 60559d1ed5bSDimitry Andric RecordStmtCount(E); 60659d1ed5bSDimitry Andric // Counter tracks the right hand side of a logical or operator. 60759d1ed5bSDimitry Andric RegionCounter Cnt(PGO, E); 60859d1ed5bSDimitry Andric Visit(E->getLHS()); 60959d1ed5bSDimitry Andric Cnt.beginRegion(); 61059d1ed5bSDimitry Andric CountMap[E->getRHS()] = PGO.getCurrentRegionCount(); 61159d1ed5bSDimitry Andric Visit(E->getRHS()); 61259d1ed5bSDimitry Andric Cnt.adjustForControlFlow(); 61359d1ed5bSDimitry Andric Cnt.applyAdjustmentsToRegion(0); 61459d1ed5bSDimitry Andric RecordNextStmtCount = true; 61559d1ed5bSDimitry Andric } 61659d1ed5bSDimitry Andric }; 61759d1ed5bSDimitry Andric } 61859d1ed5bSDimitry Andric 61959d1ed5bSDimitry Andric void PGOHash::combine(HashType Type) { 62059d1ed5bSDimitry Andric // Check that we never combine 0 and only have six bits. 62159d1ed5bSDimitry Andric assert(Type && "Hash is invalid: unexpected type 0"); 62259d1ed5bSDimitry Andric assert(unsigned(Type) < TooBig && "Hash is invalid: too many types"); 62359d1ed5bSDimitry Andric 62459d1ed5bSDimitry Andric // Pass through MD5 if enough work has built up. 62559d1ed5bSDimitry Andric if (Count && Count % NumTypesPerWord == 0) { 62659d1ed5bSDimitry Andric using namespace llvm::support; 62759d1ed5bSDimitry Andric uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working); 62859d1ed5bSDimitry Andric MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped))); 62959d1ed5bSDimitry Andric Working = 0; 63059d1ed5bSDimitry Andric } 63159d1ed5bSDimitry Andric 63259d1ed5bSDimitry Andric // Accumulate the current type. 63359d1ed5bSDimitry Andric ++Count; 63459d1ed5bSDimitry Andric Working = Working << NumBitsPerType | Type; 63559d1ed5bSDimitry Andric } 63659d1ed5bSDimitry Andric 63759d1ed5bSDimitry Andric uint64_t PGOHash::finalize() { 63859d1ed5bSDimitry Andric // Use Working as the hash directly if we never used MD5. 63959d1ed5bSDimitry Andric if (Count <= NumTypesPerWord) 64059d1ed5bSDimitry Andric // No need to byte swap here, since none of the math was endian-dependent. 64159d1ed5bSDimitry Andric // This number will be byte-swapped as required on endianness transitions, 64259d1ed5bSDimitry Andric // so we will see the same value on the other side. 64359d1ed5bSDimitry Andric return Working; 64459d1ed5bSDimitry Andric 64559d1ed5bSDimitry Andric // Check for remaining work in Working. 64659d1ed5bSDimitry Andric if (Working) 64759d1ed5bSDimitry Andric MD5.update(Working); 64859d1ed5bSDimitry Andric 64959d1ed5bSDimitry Andric // Finalize the MD5 and return the hash. 65059d1ed5bSDimitry Andric llvm::MD5::MD5Result Result; 65159d1ed5bSDimitry Andric MD5.final(Result); 65259d1ed5bSDimitry Andric using namespace llvm::support; 65359d1ed5bSDimitry Andric return endian::read<uint64_t, little, unaligned>(Result); 65459d1ed5bSDimitry Andric } 65559d1ed5bSDimitry Andric 65639d628a0SDimitry Andric void CodeGenPGO::checkGlobalDecl(GlobalDecl GD) { 65739d628a0SDimitry Andric // Make sure we only emit coverage mapping for one constructor/destructor. 65839d628a0SDimitry Andric // Clang emits several functions for the constructor and the destructor of 65939d628a0SDimitry Andric // a class. Every function is instrumented, but we only want to provide 66039d628a0SDimitry Andric // coverage for one of them. Because of that we only emit the coverage mapping 66139d628a0SDimitry Andric // for the base constructor/destructor. 66239d628a0SDimitry Andric if ((isa<CXXConstructorDecl>(GD.getDecl()) && 66339d628a0SDimitry Andric GD.getCtorType() != Ctor_Base) || 66439d628a0SDimitry Andric (isa<CXXDestructorDecl>(GD.getDecl()) && 66539d628a0SDimitry Andric GD.getDtorType() != Dtor_Base)) { 66639d628a0SDimitry Andric SkipCoverageMapping = true; 66739d628a0SDimitry Andric } 66859d1ed5bSDimitry Andric } 66959d1ed5bSDimitry Andric 67059d1ed5bSDimitry Andric void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) { 67159d1ed5bSDimitry Andric bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate; 67259d1ed5bSDimitry Andric llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader(); 67359d1ed5bSDimitry Andric if (!InstrumentRegions && !PGOReader) 67459d1ed5bSDimitry Andric return; 67559d1ed5bSDimitry Andric if (D->isImplicit()) 67659d1ed5bSDimitry Andric return; 67739d628a0SDimitry Andric CGM.ClearUnusedCoverageMapping(D); 67859d1ed5bSDimitry Andric setFuncName(Fn); 67959d1ed5bSDimitry Andric 68059d1ed5bSDimitry Andric mapRegionCounters(D); 68139d628a0SDimitry Andric if (CGM.getCodeGenOpts().CoverageMapping) 68239d628a0SDimitry Andric emitCounterRegionMapping(D); 68359d1ed5bSDimitry Andric if (PGOReader) { 68459d1ed5bSDimitry Andric SourceManager &SM = CGM.getContext().getSourceManager(); 68559d1ed5bSDimitry Andric loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation())); 68659d1ed5bSDimitry Andric computeRegionCounts(D); 68759d1ed5bSDimitry Andric applyFunctionAttributes(PGOReader, Fn); 68859d1ed5bSDimitry Andric } 68959d1ed5bSDimitry Andric } 69059d1ed5bSDimitry Andric 69159d1ed5bSDimitry Andric void CodeGenPGO::mapRegionCounters(const Decl *D) { 69259d1ed5bSDimitry Andric RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>); 69359d1ed5bSDimitry Andric MapRegionCounters Walker(*RegionCounterMap); 69459d1ed5bSDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) 69559d1ed5bSDimitry Andric Walker.TraverseDecl(const_cast<FunctionDecl *>(FD)); 69659d1ed5bSDimitry Andric else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 69759d1ed5bSDimitry Andric Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD)); 69859d1ed5bSDimitry Andric else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D)) 69959d1ed5bSDimitry Andric Walker.TraverseDecl(const_cast<BlockDecl *>(BD)); 70059d1ed5bSDimitry Andric else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D)) 70159d1ed5bSDimitry Andric Walker.TraverseDecl(const_cast<CapturedDecl *>(CD)); 70259d1ed5bSDimitry Andric assert(Walker.NextCounter > 0 && "no entry counter mapped for decl"); 70359d1ed5bSDimitry Andric NumRegionCounters = Walker.NextCounter; 70459d1ed5bSDimitry Andric FunctionHash = Walker.Hash.finalize(); 70559d1ed5bSDimitry Andric } 70659d1ed5bSDimitry Andric 70739d628a0SDimitry Andric void CodeGenPGO::emitCounterRegionMapping(const Decl *D) { 70839d628a0SDimitry Andric if (SkipCoverageMapping) 70939d628a0SDimitry Andric return; 71039d628a0SDimitry Andric // Don't map the functions inside the system headers 71139d628a0SDimitry Andric auto Loc = D->getBody()->getLocStart(); 71239d628a0SDimitry Andric if (CGM.getContext().getSourceManager().isInSystemHeader(Loc)) 71339d628a0SDimitry Andric return; 71439d628a0SDimitry Andric 71539d628a0SDimitry Andric std::string CoverageMapping; 71639d628a0SDimitry Andric llvm::raw_string_ostream OS(CoverageMapping); 71739d628a0SDimitry Andric CoverageMappingGen MappingGen(*CGM.getCoverageMapping(), 71839d628a0SDimitry Andric CGM.getContext().getSourceManager(), 71939d628a0SDimitry Andric CGM.getLangOpts(), RegionCounterMap.get()); 72039d628a0SDimitry Andric MappingGen.emitCounterMapping(D, OS); 72139d628a0SDimitry Andric OS.flush(); 72239d628a0SDimitry Andric 72339d628a0SDimitry Andric if (CoverageMapping.empty()) 72439d628a0SDimitry Andric return; 72539d628a0SDimitry Andric 72639d628a0SDimitry Andric CGM.getCoverageMapping()->addFunctionMappingRecord( 72739d628a0SDimitry Andric FuncNameVar, FuncName, FunctionHash, CoverageMapping); 72839d628a0SDimitry Andric } 72939d628a0SDimitry Andric 73039d628a0SDimitry Andric void 73139d628a0SDimitry Andric CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef FuncName, 73239d628a0SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage) { 73339d628a0SDimitry Andric if (SkipCoverageMapping) 73439d628a0SDimitry Andric return; 73539d628a0SDimitry Andric setFuncName(FuncName, Linkage); 73639d628a0SDimitry Andric 73739d628a0SDimitry Andric // Don't map the functions inside the system headers 73839d628a0SDimitry Andric auto Loc = D->getBody()->getLocStart(); 73939d628a0SDimitry Andric if (CGM.getContext().getSourceManager().isInSystemHeader(Loc)) 74039d628a0SDimitry Andric return; 74139d628a0SDimitry Andric 74239d628a0SDimitry Andric std::string CoverageMapping; 74339d628a0SDimitry Andric llvm::raw_string_ostream OS(CoverageMapping); 74439d628a0SDimitry Andric CoverageMappingGen MappingGen(*CGM.getCoverageMapping(), 74539d628a0SDimitry Andric CGM.getContext().getSourceManager(), 74639d628a0SDimitry Andric CGM.getLangOpts()); 74739d628a0SDimitry Andric MappingGen.emitEmptyMapping(D, OS); 74839d628a0SDimitry Andric OS.flush(); 74939d628a0SDimitry Andric 75039d628a0SDimitry Andric if (CoverageMapping.empty()) 75139d628a0SDimitry Andric return; 75239d628a0SDimitry Andric 75339d628a0SDimitry Andric CGM.getCoverageMapping()->addFunctionMappingRecord( 75439d628a0SDimitry Andric FuncNameVar, FuncName, FunctionHash, CoverageMapping); 75539d628a0SDimitry Andric } 75639d628a0SDimitry Andric 75759d1ed5bSDimitry Andric void CodeGenPGO::computeRegionCounts(const Decl *D) { 75859d1ed5bSDimitry Andric StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>); 75959d1ed5bSDimitry Andric ComputeRegionCounts Walker(*StmtCountMap, *this); 76059d1ed5bSDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) 76159d1ed5bSDimitry Andric Walker.VisitFunctionDecl(FD); 76259d1ed5bSDimitry Andric else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 76359d1ed5bSDimitry Andric Walker.VisitObjCMethodDecl(MD); 76459d1ed5bSDimitry Andric else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D)) 76559d1ed5bSDimitry Andric Walker.VisitBlockDecl(BD); 76659d1ed5bSDimitry Andric else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D)) 76759d1ed5bSDimitry Andric Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD)); 76859d1ed5bSDimitry Andric } 76959d1ed5bSDimitry Andric 77059d1ed5bSDimitry Andric void 77159d1ed5bSDimitry Andric CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader, 77259d1ed5bSDimitry Andric llvm::Function *Fn) { 77359d1ed5bSDimitry Andric if (!haveRegionCounts()) 77459d1ed5bSDimitry Andric return; 77559d1ed5bSDimitry Andric 77659d1ed5bSDimitry Andric uint64_t MaxFunctionCount = PGOReader->getMaximumFunctionCount(); 77759d1ed5bSDimitry Andric uint64_t FunctionCount = getRegionCount(0); 77859d1ed5bSDimitry Andric if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount)) 77959d1ed5bSDimitry Andric // Turn on InlineHint attribute for hot functions. 78059d1ed5bSDimitry Andric // FIXME: 30% is from preliminary tuning on SPEC, it may not be optimal. 78159d1ed5bSDimitry Andric Fn->addFnAttr(llvm::Attribute::InlineHint); 78259d1ed5bSDimitry Andric else if (FunctionCount <= (uint64_t)(0.01 * (double)MaxFunctionCount)) 78359d1ed5bSDimitry Andric // Turn on Cold attribute for cold functions. 78459d1ed5bSDimitry Andric // FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal. 78559d1ed5bSDimitry Andric Fn->addFnAttr(llvm::Attribute::Cold); 78659d1ed5bSDimitry Andric } 78759d1ed5bSDimitry Andric 78859d1ed5bSDimitry Andric void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) { 78939d628a0SDimitry Andric if (!CGM.getCodeGenOpts().ProfileInstrGenerate || !RegionCounterMap) 79059d1ed5bSDimitry Andric return; 79139d628a0SDimitry Andric if (!Builder.GetInsertPoint()) 79239d628a0SDimitry Andric return; 79339d628a0SDimitry Andric auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 79439d628a0SDimitry Andric Builder.CreateCall4(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment), 79539d628a0SDimitry Andric llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy), 79639d628a0SDimitry Andric Builder.getInt64(FunctionHash), 79739d628a0SDimitry Andric Builder.getInt32(NumRegionCounters), 79839d628a0SDimitry Andric Builder.getInt32(Counter)); 79959d1ed5bSDimitry Andric } 80059d1ed5bSDimitry Andric 80159d1ed5bSDimitry Andric void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader, 80259d1ed5bSDimitry Andric bool IsInMainFile) { 80359d1ed5bSDimitry Andric CGM.getPGOStats().addVisited(IsInMainFile); 80439d628a0SDimitry Andric RegionCounts.clear(); 80539d628a0SDimitry Andric if (std::error_code EC = 80639d628a0SDimitry Andric PGOReader->getFunctionCounts(FuncName, FunctionHash, RegionCounts)) { 80739d628a0SDimitry Andric if (EC == llvm::instrprof_error::unknown_function) 80859d1ed5bSDimitry Andric CGM.getPGOStats().addMissing(IsInMainFile); 80939d628a0SDimitry Andric else if (EC == llvm::instrprof_error::hash_mismatch) 81059d1ed5bSDimitry Andric CGM.getPGOStats().addMismatched(IsInMainFile); 81139d628a0SDimitry Andric else if (EC == llvm::instrprof_error::malformed) 81239d628a0SDimitry Andric // TODO: Consider a more specific warning for this case. 81339d628a0SDimitry Andric CGM.getPGOStats().addMismatched(IsInMainFile); 81439d628a0SDimitry Andric RegionCounts.clear(); 81559d1ed5bSDimitry Andric } 81659d1ed5bSDimitry Andric } 81759d1ed5bSDimitry Andric 81859d1ed5bSDimitry Andric /// \brief Calculate what to divide by to scale weights. 81959d1ed5bSDimitry Andric /// 82059d1ed5bSDimitry Andric /// Given the maximum weight, calculate a divisor that will scale all the 82159d1ed5bSDimitry Andric /// weights to strictly less than UINT32_MAX. 82259d1ed5bSDimitry Andric static uint64_t calculateWeightScale(uint64_t MaxWeight) { 82359d1ed5bSDimitry Andric return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1; 82459d1ed5bSDimitry Andric } 82559d1ed5bSDimitry Andric 82659d1ed5bSDimitry Andric /// \brief Scale an individual branch weight (and add 1). 82759d1ed5bSDimitry Andric /// 82859d1ed5bSDimitry Andric /// Scale a 64-bit weight down to 32-bits using \c Scale. 82959d1ed5bSDimitry Andric /// 83059d1ed5bSDimitry Andric /// According to Laplace's Rule of Succession, it is better to compute the 83159d1ed5bSDimitry Andric /// weight based on the count plus 1, so universally add 1 to the value. 83259d1ed5bSDimitry Andric /// 83359d1ed5bSDimitry Andric /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no 83459d1ed5bSDimitry Andric /// greater than \c Weight. 83559d1ed5bSDimitry Andric static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) { 83659d1ed5bSDimitry Andric assert(Scale && "scale by 0?"); 83759d1ed5bSDimitry Andric uint64_t Scaled = Weight / Scale + 1; 83859d1ed5bSDimitry Andric assert(Scaled <= UINT32_MAX && "overflow 32-bits"); 83959d1ed5bSDimitry Andric return Scaled; 84059d1ed5bSDimitry Andric } 84159d1ed5bSDimitry Andric 84259d1ed5bSDimitry Andric llvm::MDNode *CodeGenPGO::createBranchWeights(uint64_t TrueCount, 84359d1ed5bSDimitry Andric uint64_t FalseCount) { 84459d1ed5bSDimitry Andric // Check for empty weights. 84559d1ed5bSDimitry Andric if (!TrueCount && !FalseCount) 84659d1ed5bSDimitry Andric return nullptr; 84759d1ed5bSDimitry Andric 84859d1ed5bSDimitry Andric // Calculate how to scale down to 32-bits. 84959d1ed5bSDimitry Andric uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount)); 85059d1ed5bSDimitry Andric 85159d1ed5bSDimitry Andric llvm::MDBuilder MDHelper(CGM.getLLVMContext()); 85259d1ed5bSDimitry Andric return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale), 85359d1ed5bSDimitry Andric scaleBranchWeight(FalseCount, Scale)); 85459d1ed5bSDimitry Andric } 85559d1ed5bSDimitry Andric 85659d1ed5bSDimitry Andric llvm::MDNode *CodeGenPGO::createBranchWeights(ArrayRef<uint64_t> Weights) { 85759d1ed5bSDimitry Andric // We need at least two elements to create meaningful weights. 85859d1ed5bSDimitry Andric if (Weights.size() < 2) 85959d1ed5bSDimitry Andric return nullptr; 86059d1ed5bSDimitry Andric 86159d1ed5bSDimitry Andric // Check for empty weights. 86259d1ed5bSDimitry Andric uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end()); 86359d1ed5bSDimitry Andric if (MaxWeight == 0) 86459d1ed5bSDimitry Andric return nullptr; 86559d1ed5bSDimitry Andric 86659d1ed5bSDimitry Andric // Calculate how to scale down to 32-bits. 86759d1ed5bSDimitry Andric uint64_t Scale = calculateWeightScale(MaxWeight); 86859d1ed5bSDimitry Andric 86959d1ed5bSDimitry Andric SmallVector<uint32_t, 16> ScaledWeights; 87059d1ed5bSDimitry Andric ScaledWeights.reserve(Weights.size()); 87159d1ed5bSDimitry Andric for (uint64_t W : Weights) 87259d1ed5bSDimitry Andric ScaledWeights.push_back(scaleBranchWeight(W, Scale)); 87359d1ed5bSDimitry Andric 87459d1ed5bSDimitry Andric llvm::MDBuilder MDHelper(CGM.getLLVMContext()); 87559d1ed5bSDimitry Andric return MDHelper.createBranchWeights(ScaledWeights); 87659d1ed5bSDimitry Andric } 87759d1ed5bSDimitry Andric 87859d1ed5bSDimitry Andric llvm::MDNode *CodeGenPGO::createLoopWeights(const Stmt *Cond, 87959d1ed5bSDimitry Andric RegionCounter &Cnt) { 88059d1ed5bSDimitry Andric if (!haveRegionCounts()) 88159d1ed5bSDimitry Andric return nullptr; 88259d1ed5bSDimitry Andric uint64_t LoopCount = Cnt.getCount(); 88359d1ed5bSDimitry Andric uint64_t CondCount = 0; 88459d1ed5bSDimitry Andric bool Found = getStmtCount(Cond, CondCount); 88559d1ed5bSDimitry Andric assert(Found && "missing expected loop condition count"); 88659d1ed5bSDimitry Andric (void)Found; 88759d1ed5bSDimitry Andric if (CondCount == 0) 88859d1ed5bSDimitry Andric return nullptr; 88959d1ed5bSDimitry Andric return createBranchWeights(LoopCount, 89059d1ed5bSDimitry Andric std::max(CondCount, LoopCount) - LoopCount); 89159d1ed5bSDimitry Andric } 892