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/Support/Endian.h" 2259d1ed5bSDimitry Andric #include "llvm/Support/FileSystem.h" 2359d1ed5bSDimitry Andric #include "llvm/Support/MD5.h" 2459d1ed5bSDimitry Andric 25e7145dcbSDimitry Andric static llvm::cl::opt<bool> EnableValueProfiling( 26e7145dcbSDimitry Andric "enable-value-profiling", llvm::cl::ZeroOrMore, 27e7145dcbSDimitry Andric llvm::cl::desc("Enable value profiling"), llvm::cl::init(false)); 28e7145dcbSDimitry Andric 2959d1ed5bSDimitry Andric using namespace clang; 3059d1ed5bSDimitry Andric using namespace CodeGen; 3159d1ed5bSDimitry Andric 3239d628a0SDimitry Andric void CodeGenPGO::setFuncName(StringRef Name, 3339d628a0SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage) { 340623d748SDimitry Andric llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader(); 350623d748SDimitry Andric FuncName = llvm::getPGOFuncName( 360623d748SDimitry Andric Name, Linkage, CGM.getCodeGenOpts().MainFileName, 370623d748SDimitry Andric PGOReader ? PGOReader->getVersion() : llvm::IndexedInstrProf::Version); 3859d1ed5bSDimitry Andric 3939d628a0SDimitry Andric // If we're generating a profile, create a variable for the name. 40e7145dcbSDimitry Andric if (CGM.getCodeGenOpts().hasProfileClangInstr()) 410623d748SDimitry Andric FuncNameVar = llvm::createPGOFuncNameVar(CGM.getModule(), Linkage, FuncName); 4259d1ed5bSDimitry Andric } 4359d1ed5bSDimitry Andric 4439d628a0SDimitry Andric void CodeGenPGO::setFuncName(llvm::Function *Fn) { 4539d628a0SDimitry Andric setFuncName(Fn->getName(), Fn->getLinkage()); 46e7145dcbSDimitry Andric // Create PGOFuncName meta data. 47e7145dcbSDimitry Andric llvm::createPGOFuncNameMetadata(*Fn, FuncName); 4859d1ed5bSDimitry Andric } 4959d1ed5bSDimitry Andric 5059d1ed5bSDimitry Andric namespace { 5159d1ed5bSDimitry Andric /// \brief Stable hasher for PGO region counters. 5259d1ed5bSDimitry Andric /// 5359d1ed5bSDimitry Andric /// PGOHash produces a stable hash of a given function's control flow. 5459d1ed5bSDimitry Andric /// 5559d1ed5bSDimitry Andric /// Changing the output of this hash will invalidate all previously generated 5659d1ed5bSDimitry Andric /// profiles -- i.e., don't do it. 5759d1ed5bSDimitry Andric /// 5859d1ed5bSDimitry Andric /// \note When this hash does eventually change (years?), we still need to 5959d1ed5bSDimitry Andric /// support old hashes. We'll need to pull in the version number from the 6059d1ed5bSDimitry Andric /// profile data format and use the matching hash function. 6159d1ed5bSDimitry Andric class PGOHash { 6259d1ed5bSDimitry Andric uint64_t Working; 6359d1ed5bSDimitry Andric unsigned Count; 6459d1ed5bSDimitry Andric llvm::MD5 MD5; 6559d1ed5bSDimitry Andric 6659d1ed5bSDimitry Andric static const int NumBitsPerType = 6; 6759d1ed5bSDimitry Andric static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType; 6859d1ed5bSDimitry Andric static const unsigned TooBig = 1u << NumBitsPerType; 6959d1ed5bSDimitry Andric 7059d1ed5bSDimitry Andric public: 7159d1ed5bSDimitry Andric /// \brief Hash values for AST nodes. 7259d1ed5bSDimitry Andric /// 7359d1ed5bSDimitry Andric /// Distinct values for AST nodes that have region counters attached. 7459d1ed5bSDimitry Andric /// 7559d1ed5bSDimitry Andric /// These values must be stable. All new members must be added at the end, 7659d1ed5bSDimitry Andric /// and no members should be removed. Changing the enumeration value for an 7759d1ed5bSDimitry Andric /// AST node will affect the hash of every function that contains that node. 7859d1ed5bSDimitry Andric enum HashType : unsigned char { 7959d1ed5bSDimitry Andric None = 0, 8059d1ed5bSDimitry Andric LabelStmt = 1, 8159d1ed5bSDimitry Andric WhileStmt, 8259d1ed5bSDimitry Andric DoStmt, 8359d1ed5bSDimitry Andric ForStmt, 8459d1ed5bSDimitry Andric CXXForRangeStmt, 8559d1ed5bSDimitry Andric ObjCForCollectionStmt, 8659d1ed5bSDimitry Andric SwitchStmt, 8759d1ed5bSDimitry Andric CaseStmt, 8859d1ed5bSDimitry Andric DefaultStmt, 8959d1ed5bSDimitry Andric IfStmt, 9059d1ed5bSDimitry Andric CXXTryStmt, 9159d1ed5bSDimitry Andric CXXCatchStmt, 9259d1ed5bSDimitry Andric ConditionalOperator, 9359d1ed5bSDimitry Andric BinaryOperatorLAnd, 9459d1ed5bSDimitry Andric BinaryOperatorLOr, 9559d1ed5bSDimitry Andric BinaryConditionalOperator, 9659d1ed5bSDimitry Andric 9759d1ed5bSDimitry Andric // Keep this last. It's for the static assert that follows. 9859d1ed5bSDimitry Andric LastHashType 9959d1ed5bSDimitry Andric }; 10059d1ed5bSDimitry Andric static_assert(LastHashType <= TooBig, "Too many types in HashType"); 10159d1ed5bSDimitry Andric 10259d1ed5bSDimitry Andric // TODO: When this format changes, take in a version number here, and use the 10359d1ed5bSDimitry Andric // old hash calculation for file formats that used the old hash. 10459d1ed5bSDimitry Andric PGOHash() : Working(0), Count(0) {} 10559d1ed5bSDimitry Andric void combine(HashType Type); 10659d1ed5bSDimitry Andric uint64_t finalize(); 10759d1ed5bSDimitry Andric }; 10859d1ed5bSDimitry Andric const int PGOHash::NumBitsPerType; 10959d1ed5bSDimitry Andric const unsigned PGOHash::NumTypesPerWord; 11059d1ed5bSDimitry Andric const unsigned PGOHash::TooBig; 11159d1ed5bSDimitry Andric 11259d1ed5bSDimitry Andric /// A RecursiveASTVisitor that fills a map of statements to PGO counters. 11359d1ed5bSDimitry Andric struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> { 11459d1ed5bSDimitry Andric /// The next counter value to assign. 11559d1ed5bSDimitry Andric unsigned NextCounter; 11659d1ed5bSDimitry Andric /// The function hash. 11759d1ed5bSDimitry Andric PGOHash Hash; 11859d1ed5bSDimitry Andric /// The map of statements to counters. 11959d1ed5bSDimitry Andric llvm::DenseMap<const Stmt *, unsigned> &CounterMap; 12059d1ed5bSDimitry Andric 12159d1ed5bSDimitry Andric MapRegionCounters(llvm::DenseMap<const Stmt *, unsigned> &CounterMap) 12259d1ed5bSDimitry Andric : NextCounter(0), CounterMap(CounterMap) {} 12359d1ed5bSDimitry Andric 12459d1ed5bSDimitry Andric // Blocks and lambdas are handled as separate functions, so we need not 12559d1ed5bSDimitry Andric // traverse them in the parent context. 12659d1ed5bSDimitry Andric bool TraverseBlockExpr(BlockExpr *BE) { return true; } 12759d1ed5bSDimitry Andric bool TraverseLambdaBody(LambdaExpr *LE) { return true; } 12859d1ed5bSDimitry Andric bool TraverseCapturedStmt(CapturedStmt *CS) { return true; } 12959d1ed5bSDimitry Andric 13059d1ed5bSDimitry Andric bool VisitDecl(const Decl *D) { 13159d1ed5bSDimitry Andric switch (D->getKind()) { 13259d1ed5bSDimitry Andric default: 13359d1ed5bSDimitry Andric break; 13459d1ed5bSDimitry Andric case Decl::Function: 13559d1ed5bSDimitry Andric case Decl::CXXMethod: 13659d1ed5bSDimitry Andric case Decl::CXXConstructor: 13759d1ed5bSDimitry Andric case Decl::CXXDestructor: 13859d1ed5bSDimitry Andric case Decl::CXXConversion: 13959d1ed5bSDimitry Andric case Decl::ObjCMethod: 14059d1ed5bSDimitry Andric case Decl::Block: 14159d1ed5bSDimitry Andric case Decl::Captured: 14259d1ed5bSDimitry Andric CounterMap[D->getBody()] = NextCounter++; 14359d1ed5bSDimitry Andric break; 14459d1ed5bSDimitry Andric } 14559d1ed5bSDimitry Andric return true; 14659d1ed5bSDimitry Andric } 14759d1ed5bSDimitry Andric 14859d1ed5bSDimitry Andric bool VisitStmt(const Stmt *S) { 14959d1ed5bSDimitry Andric auto Type = getHashType(S); 15059d1ed5bSDimitry Andric if (Type == PGOHash::None) 15159d1ed5bSDimitry Andric return true; 15259d1ed5bSDimitry Andric 15359d1ed5bSDimitry Andric CounterMap[S] = NextCounter++; 15459d1ed5bSDimitry Andric Hash.combine(Type); 15559d1ed5bSDimitry Andric return true; 15659d1ed5bSDimitry Andric } 15759d1ed5bSDimitry Andric PGOHash::HashType getHashType(const Stmt *S) { 15859d1ed5bSDimitry Andric switch (S->getStmtClass()) { 15959d1ed5bSDimitry Andric default: 16059d1ed5bSDimitry Andric break; 16159d1ed5bSDimitry Andric case Stmt::LabelStmtClass: 16259d1ed5bSDimitry Andric return PGOHash::LabelStmt; 16359d1ed5bSDimitry Andric case Stmt::WhileStmtClass: 16459d1ed5bSDimitry Andric return PGOHash::WhileStmt; 16559d1ed5bSDimitry Andric case Stmt::DoStmtClass: 16659d1ed5bSDimitry Andric return PGOHash::DoStmt; 16759d1ed5bSDimitry Andric case Stmt::ForStmtClass: 16859d1ed5bSDimitry Andric return PGOHash::ForStmt; 16959d1ed5bSDimitry Andric case Stmt::CXXForRangeStmtClass: 17059d1ed5bSDimitry Andric return PGOHash::CXXForRangeStmt; 17159d1ed5bSDimitry Andric case Stmt::ObjCForCollectionStmtClass: 17259d1ed5bSDimitry Andric return PGOHash::ObjCForCollectionStmt; 17359d1ed5bSDimitry Andric case Stmt::SwitchStmtClass: 17459d1ed5bSDimitry Andric return PGOHash::SwitchStmt; 17559d1ed5bSDimitry Andric case Stmt::CaseStmtClass: 17659d1ed5bSDimitry Andric return PGOHash::CaseStmt; 17759d1ed5bSDimitry Andric case Stmt::DefaultStmtClass: 17859d1ed5bSDimitry Andric return PGOHash::DefaultStmt; 17959d1ed5bSDimitry Andric case Stmt::IfStmtClass: 18059d1ed5bSDimitry Andric return PGOHash::IfStmt; 18159d1ed5bSDimitry Andric case Stmt::CXXTryStmtClass: 18259d1ed5bSDimitry Andric return PGOHash::CXXTryStmt; 18359d1ed5bSDimitry Andric case Stmt::CXXCatchStmtClass: 18459d1ed5bSDimitry Andric return PGOHash::CXXCatchStmt; 18559d1ed5bSDimitry Andric case Stmt::ConditionalOperatorClass: 18659d1ed5bSDimitry Andric return PGOHash::ConditionalOperator; 18759d1ed5bSDimitry Andric case Stmt::BinaryConditionalOperatorClass: 18859d1ed5bSDimitry Andric return PGOHash::BinaryConditionalOperator; 18959d1ed5bSDimitry Andric case Stmt::BinaryOperatorClass: { 19059d1ed5bSDimitry Andric const BinaryOperator *BO = cast<BinaryOperator>(S); 19159d1ed5bSDimitry Andric if (BO->getOpcode() == BO_LAnd) 19259d1ed5bSDimitry Andric return PGOHash::BinaryOperatorLAnd; 19359d1ed5bSDimitry Andric if (BO->getOpcode() == BO_LOr) 19459d1ed5bSDimitry Andric return PGOHash::BinaryOperatorLOr; 19559d1ed5bSDimitry Andric break; 19659d1ed5bSDimitry Andric } 19759d1ed5bSDimitry Andric } 19859d1ed5bSDimitry Andric return PGOHash::None; 19959d1ed5bSDimitry Andric } 20059d1ed5bSDimitry Andric }; 20159d1ed5bSDimitry Andric 20259d1ed5bSDimitry Andric /// A StmtVisitor that propagates the raw counts through the AST and 20359d1ed5bSDimitry Andric /// records the count at statements where the value may change. 20459d1ed5bSDimitry Andric struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> { 20559d1ed5bSDimitry Andric /// PGO state. 20659d1ed5bSDimitry Andric CodeGenPGO &PGO; 20759d1ed5bSDimitry Andric 20859d1ed5bSDimitry Andric /// A flag that is set when the current count should be recorded on the 20959d1ed5bSDimitry Andric /// next statement, such as at the exit of a loop. 21059d1ed5bSDimitry Andric bool RecordNextStmtCount; 21159d1ed5bSDimitry Andric 21233956c43SDimitry Andric /// The count at the current location in the traversal. 21333956c43SDimitry Andric uint64_t CurrentCount; 21433956c43SDimitry Andric 21559d1ed5bSDimitry Andric /// The map of statements to count values. 21659d1ed5bSDimitry Andric llvm::DenseMap<const Stmt *, uint64_t> &CountMap; 21759d1ed5bSDimitry Andric 21859d1ed5bSDimitry Andric /// BreakContinueStack - Keep counts of breaks and continues inside loops. 21959d1ed5bSDimitry Andric struct BreakContinue { 22059d1ed5bSDimitry Andric uint64_t BreakCount; 22159d1ed5bSDimitry Andric uint64_t ContinueCount; 22259d1ed5bSDimitry Andric BreakContinue() : BreakCount(0), ContinueCount(0) {} 22359d1ed5bSDimitry Andric }; 22459d1ed5bSDimitry Andric SmallVector<BreakContinue, 8> BreakContinueStack; 22559d1ed5bSDimitry Andric 22659d1ed5bSDimitry Andric ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap, 22759d1ed5bSDimitry Andric CodeGenPGO &PGO) 22859d1ed5bSDimitry Andric : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {} 22959d1ed5bSDimitry Andric 23059d1ed5bSDimitry Andric void RecordStmtCount(const Stmt *S) { 23159d1ed5bSDimitry Andric if (RecordNextStmtCount) { 23233956c43SDimitry Andric CountMap[S] = CurrentCount; 23359d1ed5bSDimitry Andric RecordNextStmtCount = false; 23459d1ed5bSDimitry Andric } 23559d1ed5bSDimitry Andric } 23659d1ed5bSDimitry Andric 23733956c43SDimitry Andric /// Set and return the current count. 23833956c43SDimitry Andric uint64_t setCount(uint64_t Count) { 23933956c43SDimitry Andric CurrentCount = Count; 24033956c43SDimitry Andric return Count; 24133956c43SDimitry Andric } 24233956c43SDimitry Andric 24359d1ed5bSDimitry Andric void VisitStmt(const Stmt *S) { 24459d1ed5bSDimitry Andric RecordStmtCount(S); 2453dac3a9bSDimitry Andric for (const Stmt *Child : S->children()) 2463dac3a9bSDimitry Andric if (Child) 2473dac3a9bSDimitry Andric this->Visit(Child); 24859d1ed5bSDimitry Andric } 24959d1ed5bSDimitry Andric 25059d1ed5bSDimitry Andric void VisitFunctionDecl(const FunctionDecl *D) { 25159d1ed5bSDimitry Andric // Counter tracks entry to the function body. 25233956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody())); 25333956c43SDimitry Andric CountMap[D->getBody()] = BodyCount; 25459d1ed5bSDimitry Andric Visit(D->getBody()); 25559d1ed5bSDimitry Andric } 25659d1ed5bSDimitry Andric 25759d1ed5bSDimitry Andric // Skip lambda expressions. We visit these as FunctionDecls when we're 25859d1ed5bSDimitry Andric // generating them and aren't interested in the body when generating a 25959d1ed5bSDimitry Andric // parent context. 26059d1ed5bSDimitry Andric void VisitLambdaExpr(const LambdaExpr *LE) {} 26159d1ed5bSDimitry Andric 26259d1ed5bSDimitry Andric void VisitCapturedDecl(const CapturedDecl *D) { 26359d1ed5bSDimitry Andric // Counter tracks entry to the capture body. 26433956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody())); 26533956c43SDimitry Andric CountMap[D->getBody()] = BodyCount; 26659d1ed5bSDimitry Andric Visit(D->getBody()); 26759d1ed5bSDimitry Andric } 26859d1ed5bSDimitry Andric 26959d1ed5bSDimitry Andric void VisitObjCMethodDecl(const ObjCMethodDecl *D) { 27059d1ed5bSDimitry Andric // Counter tracks entry to the method body. 27133956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody())); 27233956c43SDimitry Andric CountMap[D->getBody()] = BodyCount; 27359d1ed5bSDimitry Andric Visit(D->getBody()); 27459d1ed5bSDimitry Andric } 27559d1ed5bSDimitry Andric 27659d1ed5bSDimitry Andric void VisitBlockDecl(const BlockDecl *D) { 27759d1ed5bSDimitry Andric // Counter tracks entry to the block body. 27833956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody())); 27933956c43SDimitry Andric CountMap[D->getBody()] = BodyCount; 28059d1ed5bSDimitry Andric Visit(D->getBody()); 28159d1ed5bSDimitry Andric } 28259d1ed5bSDimitry Andric 28359d1ed5bSDimitry Andric void VisitReturnStmt(const ReturnStmt *S) { 28459d1ed5bSDimitry Andric RecordStmtCount(S); 28559d1ed5bSDimitry Andric if (S->getRetValue()) 28659d1ed5bSDimitry Andric Visit(S->getRetValue()); 28733956c43SDimitry Andric CurrentCount = 0; 28833956c43SDimitry Andric RecordNextStmtCount = true; 28933956c43SDimitry Andric } 29033956c43SDimitry Andric 29133956c43SDimitry Andric void VisitCXXThrowExpr(const CXXThrowExpr *E) { 29233956c43SDimitry Andric RecordStmtCount(E); 29333956c43SDimitry Andric if (E->getSubExpr()) 29433956c43SDimitry Andric Visit(E->getSubExpr()); 29533956c43SDimitry Andric CurrentCount = 0; 29659d1ed5bSDimitry Andric RecordNextStmtCount = true; 29759d1ed5bSDimitry Andric } 29859d1ed5bSDimitry Andric 29959d1ed5bSDimitry Andric void VisitGotoStmt(const GotoStmt *S) { 30059d1ed5bSDimitry Andric RecordStmtCount(S); 30133956c43SDimitry Andric CurrentCount = 0; 30259d1ed5bSDimitry Andric RecordNextStmtCount = true; 30359d1ed5bSDimitry Andric } 30459d1ed5bSDimitry Andric 30559d1ed5bSDimitry Andric void VisitLabelStmt(const LabelStmt *S) { 30659d1ed5bSDimitry Andric RecordNextStmtCount = false; 30759d1ed5bSDimitry Andric // Counter tracks the block following the label. 30833956c43SDimitry Andric uint64_t BlockCount = setCount(PGO.getRegionCount(S)); 30933956c43SDimitry Andric CountMap[S] = BlockCount; 31059d1ed5bSDimitry Andric Visit(S->getSubStmt()); 31159d1ed5bSDimitry Andric } 31259d1ed5bSDimitry Andric 31359d1ed5bSDimitry Andric void VisitBreakStmt(const BreakStmt *S) { 31459d1ed5bSDimitry Andric RecordStmtCount(S); 31559d1ed5bSDimitry Andric assert(!BreakContinueStack.empty() && "break not in a loop or switch!"); 31633956c43SDimitry Andric BreakContinueStack.back().BreakCount += CurrentCount; 31733956c43SDimitry Andric CurrentCount = 0; 31859d1ed5bSDimitry Andric RecordNextStmtCount = true; 31959d1ed5bSDimitry Andric } 32059d1ed5bSDimitry Andric 32159d1ed5bSDimitry Andric void VisitContinueStmt(const ContinueStmt *S) { 32259d1ed5bSDimitry Andric RecordStmtCount(S); 32359d1ed5bSDimitry Andric assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 32433956c43SDimitry Andric BreakContinueStack.back().ContinueCount += CurrentCount; 32533956c43SDimitry Andric CurrentCount = 0; 32659d1ed5bSDimitry Andric RecordNextStmtCount = true; 32759d1ed5bSDimitry Andric } 32859d1ed5bSDimitry Andric 32959d1ed5bSDimitry Andric void VisitWhileStmt(const WhileStmt *S) { 33059d1ed5bSDimitry Andric RecordStmtCount(S); 33133956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 33233956c43SDimitry Andric 33359d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 33459d1ed5bSDimitry Andric // Visit the body region first so the break/continue adjustments can be 33559d1ed5bSDimitry Andric // included when visiting the condition. 33633956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(S)); 33733956c43SDimitry Andric CountMap[S->getBody()] = CurrentCount; 33859d1ed5bSDimitry Andric Visit(S->getBody()); 33933956c43SDimitry Andric uint64_t BackedgeCount = CurrentCount; 34059d1ed5bSDimitry Andric 34159d1ed5bSDimitry Andric // ...then go back and propagate counts through the condition. The count 34259d1ed5bSDimitry Andric // at the start of the condition is the sum of the incoming edges, 34359d1ed5bSDimitry Andric // the backedge from the end of the loop body, and the edges from 34459d1ed5bSDimitry Andric // continue statements. 34559d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 34633956c43SDimitry Andric uint64_t CondCount = 34733956c43SDimitry Andric setCount(ParentCount + BackedgeCount + BC.ContinueCount); 34833956c43SDimitry Andric CountMap[S->getCond()] = CondCount; 34959d1ed5bSDimitry Andric Visit(S->getCond()); 35033956c43SDimitry Andric setCount(BC.BreakCount + CondCount - BodyCount); 35159d1ed5bSDimitry Andric RecordNextStmtCount = true; 35259d1ed5bSDimitry Andric } 35359d1ed5bSDimitry Andric 35459d1ed5bSDimitry Andric void VisitDoStmt(const DoStmt *S) { 35559d1ed5bSDimitry Andric RecordStmtCount(S); 35633956c43SDimitry Andric uint64_t LoopCount = PGO.getRegionCount(S); 35733956c43SDimitry Andric 35859d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 35933956c43SDimitry Andric // The count doesn't include the fallthrough from the parent scope. Add it. 36033956c43SDimitry Andric uint64_t BodyCount = setCount(LoopCount + CurrentCount); 36133956c43SDimitry Andric CountMap[S->getBody()] = BodyCount; 36259d1ed5bSDimitry Andric Visit(S->getBody()); 36333956c43SDimitry Andric uint64_t BackedgeCount = CurrentCount; 36459d1ed5bSDimitry Andric 36559d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 36659d1ed5bSDimitry Andric // The count at the start of the condition is equal to the count at the 36733956c43SDimitry Andric // end of the body, plus any continues. 36833956c43SDimitry Andric uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount); 36933956c43SDimitry Andric CountMap[S->getCond()] = CondCount; 37059d1ed5bSDimitry Andric Visit(S->getCond()); 37133956c43SDimitry Andric setCount(BC.BreakCount + CondCount - LoopCount); 37259d1ed5bSDimitry Andric RecordNextStmtCount = true; 37359d1ed5bSDimitry Andric } 37459d1ed5bSDimitry Andric 37559d1ed5bSDimitry Andric void VisitForStmt(const ForStmt *S) { 37659d1ed5bSDimitry Andric RecordStmtCount(S); 37759d1ed5bSDimitry Andric if (S->getInit()) 37859d1ed5bSDimitry Andric Visit(S->getInit()); 37933956c43SDimitry Andric 38033956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 38133956c43SDimitry Andric 38259d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 38359d1ed5bSDimitry Andric // Visit the body region first. (This is basically the same as a while 38459d1ed5bSDimitry Andric // loop; see further comments in VisitWhileStmt.) 38533956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(S)); 38633956c43SDimitry Andric CountMap[S->getBody()] = BodyCount; 38759d1ed5bSDimitry Andric Visit(S->getBody()); 38833956c43SDimitry Andric uint64_t BackedgeCount = CurrentCount; 38933956c43SDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 39059d1ed5bSDimitry Andric 39159d1ed5bSDimitry Andric // The increment is essentially part of the body but it needs to include 39259d1ed5bSDimitry Andric // the count for all the continue statements. 39359d1ed5bSDimitry Andric if (S->getInc()) { 39433956c43SDimitry Andric uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount); 39533956c43SDimitry Andric CountMap[S->getInc()] = IncCount; 39659d1ed5bSDimitry Andric Visit(S->getInc()); 39759d1ed5bSDimitry Andric } 39859d1ed5bSDimitry Andric 39959d1ed5bSDimitry Andric // ...then go back and propagate counts through the condition. 40033956c43SDimitry Andric uint64_t CondCount = 40133956c43SDimitry Andric setCount(ParentCount + BackedgeCount + BC.ContinueCount); 40259d1ed5bSDimitry Andric if (S->getCond()) { 40333956c43SDimitry Andric CountMap[S->getCond()] = CondCount; 40459d1ed5bSDimitry Andric Visit(S->getCond()); 40559d1ed5bSDimitry Andric } 40633956c43SDimitry Andric setCount(BC.BreakCount + CondCount - BodyCount); 40759d1ed5bSDimitry Andric RecordNextStmtCount = true; 40859d1ed5bSDimitry Andric } 40959d1ed5bSDimitry Andric 41059d1ed5bSDimitry Andric void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { 41159d1ed5bSDimitry Andric RecordStmtCount(S); 41233956c43SDimitry Andric Visit(S->getLoopVarStmt()); 41359d1ed5bSDimitry Andric Visit(S->getRangeStmt()); 414e7145dcbSDimitry Andric Visit(S->getBeginStmt()); 415e7145dcbSDimitry Andric Visit(S->getEndStmt()); 41633956c43SDimitry Andric 41733956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 41859d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 41959d1ed5bSDimitry Andric // Visit the body region first. (This is basically the same as a while 42059d1ed5bSDimitry Andric // loop; see further comments in VisitWhileStmt.) 42133956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(S)); 42233956c43SDimitry Andric CountMap[S->getBody()] = BodyCount; 42359d1ed5bSDimitry Andric Visit(S->getBody()); 42433956c43SDimitry Andric uint64_t BackedgeCount = CurrentCount; 42533956c43SDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 42659d1ed5bSDimitry Andric 42759d1ed5bSDimitry Andric // The increment is essentially part of the body but it needs to include 42859d1ed5bSDimitry Andric // the count for all the continue statements. 42933956c43SDimitry Andric uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount); 43033956c43SDimitry Andric CountMap[S->getInc()] = IncCount; 43159d1ed5bSDimitry Andric Visit(S->getInc()); 43259d1ed5bSDimitry Andric 43359d1ed5bSDimitry Andric // ...then go back and propagate counts through the condition. 43433956c43SDimitry Andric uint64_t CondCount = 43533956c43SDimitry Andric setCount(ParentCount + BackedgeCount + BC.ContinueCount); 43633956c43SDimitry Andric CountMap[S->getCond()] = CondCount; 43759d1ed5bSDimitry Andric Visit(S->getCond()); 43833956c43SDimitry Andric setCount(BC.BreakCount + CondCount - BodyCount); 43959d1ed5bSDimitry Andric RecordNextStmtCount = true; 44059d1ed5bSDimitry Andric } 44159d1ed5bSDimitry Andric 44259d1ed5bSDimitry Andric void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { 44359d1ed5bSDimitry Andric RecordStmtCount(S); 44459d1ed5bSDimitry Andric Visit(S->getElement()); 44533956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 44659d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 44733956c43SDimitry Andric // Counter tracks the body of the loop. 44833956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(S)); 44933956c43SDimitry Andric CountMap[S->getBody()] = BodyCount; 45059d1ed5bSDimitry Andric Visit(S->getBody()); 45133956c43SDimitry Andric uint64_t BackedgeCount = CurrentCount; 45259d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 45333956c43SDimitry Andric 45433956c43SDimitry Andric setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount - 45533956c43SDimitry Andric BodyCount); 45659d1ed5bSDimitry Andric RecordNextStmtCount = true; 45759d1ed5bSDimitry Andric } 45859d1ed5bSDimitry Andric 45959d1ed5bSDimitry Andric void VisitSwitchStmt(const SwitchStmt *S) { 46059d1ed5bSDimitry Andric RecordStmtCount(S); 46159d1ed5bSDimitry Andric Visit(S->getCond()); 46233956c43SDimitry Andric CurrentCount = 0; 46359d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 46459d1ed5bSDimitry Andric Visit(S->getBody()); 46559d1ed5bSDimitry Andric // If the switch is inside a loop, add the continue counts. 46659d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 46759d1ed5bSDimitry Andric if (!BreakContinueStack.empty()) 46859d1ed5bSDimitry Andric BreakContinueStack.back().ContinueCount += BC.ContinueCount; 46959d1ed5bSDimitry Andric // Counter tracks the exit block of the switch. 47033956c43SDimitry Andric setCount(PGO.getRegionCount(S)); 47159d1ed5bSDimitry Andric RecordNextStmtCount = true; 47259d1ed5bSDimitry Andric } 47359d1ed5bSDimitry Andric 47433956c43SDimitry Andric void VisitSwitchCase(const SwitchCase *S) { 47559d1ed5bSDimitry Andric RecordNextStmtCount = false; 47659d1ed5bSDimitry Andric // Counter for this particular case. This counts only jumps from the 47759d1ed5bSDimitry Andric // switch header and does not include fallthrough from the case before 47859d1ed5bSDimitry Andric // this one. 47933956c43SDimitry Andric uint64_t CaseCount = PGO.getRegionCount(S); 48033956c43SDimitry Andric setCount(CurrentCount + CaseCount); 48133956c43SDimitry Andric // We need the count without fallthrough in the mapping, so it's more useful 48233956c43SDimitry Andric // for branch probabilities. 48333956c43SDimitry Andric CountMap[S] = CaseCount; 48459d1ed5bSDimitry Andric RecordNextStmtCount = true; 48559d1ed5bSDimitry Andric Visit(S->getSubStmt()); 48659d1ed5bSDimitry Andric } 48759d1ed5bSDimitry Andric 48859d1ed5bSDimitry Andric void VisitIfStmt(const IfStmt *S) { 48959d1ed5bSDimitry Andric RecordStmtCount(S); 49033956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 49159d1ed5bSDimitry Andric Visit(S->getCond()); 49259d1ed5bSDimitry Andric 49333956c43SDimitry Andric // Counter tracks the "then" part of an if statement. The count for 49433956c43SDimitry Andric // the "else" part, if it exists, will be calculated from this counter. 49533956c43SDimitry Andric uint64_t ThenCount = setCount(PGO.getRegionCount(S)); 49633956c43SDimitry Andric CountMap[S->getThen()] = ThenCount; 49759d1ed5bSDimitry Andric Visit(S->getThen()); 49833956c43SDimitry Andric uint64_t OutCount = CurrentCount; 49959d1ed5bSDimitry Andric 50033956c43SDimitry Andric uint64_t ElseCount = ParentCount - ThenCount; 50159d1ed5bSDimitry Andric if (S->getElse()) { 50233956c43SDimitry Andric setCount(ElseCount); 50333956c43SDimitry Andric CountMap[S->getElse()] = ElseCount; 50459d1ed5bSDimitry Andric Visit(S->getElse()); 50533956c43SDimitry Andric OutCount += CurrentCount; 50633956c43SDimitry Andric } else 50733956c43SDimitry Andric OutCount += ElseCount; 50833956c43SDimitry Andric setCount(OutCount); 50959d1ed5bSDimitry Andric RecordNextStmtCount = true; 51059d1ed5bSDimitry Andric } 51159d1ed5bSDimitry Andric 51259d1ed5bSDimitry Andric void VisitCXXTryStmt(const CXXTryStmt *S) { 51359d1ed5bSDimitry Andric RecordStmtCount(S); 51459d1ed5bSDimitry Andric Visit(S->getTryBlock()); 51559d1ed5bSDimitry Andric for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I) 51659d1ed5bSDimitry Andric Visit(S->getHandler(I)); 51759d1ed5bSDimitry Andric // Counter tracks the continuation block of the try statement. 51833956c43SDimitry Andric setCount(PGO.getRegionCount(S)); 51959d1ed5bSDimitry Andric RecordNextStmtCount = true; 52059d1ed5bSDimitry Andric } 52159d1ed5bSDimitry Andric 52259d1ed5bSDimitry Andric void VisitCXXCatchStmt(const CXXCatchStmt *S) { 52359d1ed5bSDimitry Andric RecordNextStmtCount = false; 52459d1ed5bSDimitry Andric // Counter tracks the catch statement's handler block. 52533956c43SDimitry Andric uint64_t CatchCount = setCount(PGO.getRegionCount(S)); 52633956c43SDimitry Andric CountMap[S] = CatchCount; 52759d1ed5bSDimitry Andric Visit(S->getHandlerBlock()); 52859d1ed5bSDimitry Andric } 52959d1ed5bSDimitry Andric 53033956c43SDimitry Andric void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { 53159d1ed5bSDimitry Andric RecordStmtCount(E); 53233956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 53359d1ed5bSDimitry Andric Visit(E->getCond()); 53459d1ed5bSDimitry Andric 53533956c43SDimitry Andric // Counter tracks the "true" part of a conditional operator. The 53633956c43SDimitry Andric // count in the "false" part will be calculated from this counter. 53733956c43SDimitry Andric uint64_t TrueCount = setCount(PGO.getRegionCount(E)); 53833956c43SDimitry Andric CountMap[E->getTrueExpr()] = TrueCount; 53959d1ed5bSDimitry Andric Visit(E->getTrueExpr()); 54033956c43SDimitry Andric uint64_t OutCount = CurrentCount; 54159d1ed5bSDimitry Andric 54233956c43SDimitry Andric uint64_t FalseCount = setCount(ParentCount - TrueCount); 54333956c43SDimitry Andric CountMap[E->getFalseExpr()] = FalseCount; 54459d1ed5bSDimitry Andric Visit(E->getFalseExpr()); 54533956c43SDimitry Andric OutCount += CurrentCount; 54659d1ed5bSDimitry Andric 54733956c43SDimitry Andric setCount(OutCount); 54859d1ed5bSDimitry Andric RecordNextStmtCount = true; 54959d1ed5bSDimitry Andric } 55059d1ed5bSDimitry Andric 55159d1ed5bSDimitry Andric void VisitBinLAnd(const BinaryOperator *E) { 55259d1ed5bSDimitry Andric RecordStmtCount(E); 55333956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 55459d1ed5bSDimitry Andric Visit(E->getLHS()); 55533956c43SDimitry Andric // Counter tracks the right hand side of a logical and operator. 55633956c43SDimitry Andric uint64_t RHSCount = setCount(PGO.getRegionCount(E)); 55733956c43SDimitry Andric CountMap[E->getRHS()] = RHSCount; 55859d1ed5bSDimitry Andric Visit(E->getRHS()); 55933956c43SDimitry Andric setCount(ParentCount + RHSCount - CurrentCount); 56059d1ed5bSDimitry Andric RecordNextStmtCount = true; 56159d1ed5bSDimitry Andric } 56259d1ed5bSDimitry Andric 56359d1ed5bSDimitry Andric void VisitBinLOr(const BinaryOperator *E) { 56459d1ed5bSDimitry Andric RecordStmtCount(E); 56533956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 56659d1ed5bSDimitry Andric Visit(E->getLHS()); 56733956c43SDimitry Andric // Counter tracks the right hand side of a logical or operator. 56833956c43SDimitry Andric uint64_t RHSCount = setCount(PGO.getRegionCount(E)); 56933956c43SDimitry Andric CountMap[E->getRHS()] = RHSCount; 57059d1ed5bSDimitry Andric Visit(E->getRHS()); 57133956c43SDimitry Andric setCount(ParentCount + RHSCount - CurrentCount); 57259d1ed5bSDimitry Andric RecordNextStmtCount = true; 57359d1ed5bSDimitry Andric } 57459d1ed5bSDimitry Andric }; 5750623d748SDimitry Andric } // end anonymous namespace 57659d1ed5bSDimitry Andric 57759d1ed5bSDimitry Andric void PGOHash::combine(HashType Type) { 57859d1ed5bSDimitry Andric // Check that we never combine 0 and only have six bits. 57959d1ed5bSDimitry Andric assert(Type && "Hash is invalid: unexpected type 0"); 58059d1ed5bSDimitry Andric assert(unsigned(Type) < TooBig && "Hash is invalid: too many types"); 58159d1ed5bSDimitry Andric 58259d1ed5bSDimitry Andric // Pass through MD5 if enough work has built up. 58359d1ed5bSDimitry Andric if (Count && Count % NumTypesPerWord == 0) { 58459d1ed5bSDimitry Andric using namespace llvm::support; 58559d1ed5bSDimitry Andric uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working); 58659d1ed5bSDimitry Andric MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped))); 58759d1ed5bSDimitry Andric Working = 0; 58859d1ed5bSDimitry Andric } 58959d1ed5bSDimitry Andric 59059d1ed5bSDimitry Andric // Accumulate the current type. 59159d1ed5bSDimitry Andric ++Count; 59259d1ed5bSDimitry Andric Working = Working << NumBitsPerType | Type; 59359d1ed5bSDimitry Andric } 59459d1ed5bSDimitry Andric 59559d1ed5bSDimitry Andric uint64_t PGOHash::finalize() { 59659d1ed5bSDimitry Andric // Use Working as the hash directly if we never used MD5. 59759d1ed5bSDimitry Andric if (Count <= NumTypesPerWord) 59859d1ed5bSDimitry Andric // No need to byte swap here, since none of the math was endian-dependent. 59959d1ed5bSDimitry Andric // This number will be byte-swapped as required on endianness transitions, 60059d1ed5bSDimitry Andric // so we will see the same value on the other side. 60159d1ed5bSDimitry Andric return Working; 60259d1ed5bSDimitry Andric 60359d1ed5bSDimitry Andric // Check for remaining work in Working. 60459d1ed5bSDimitry Andric if (Working) 60559d1ed5bSDimitry Andric MD5.update(Working); 60659d1ed5bSDimitry Andric 60759d1ed5bSDimitry Andric // Finalize the MD5 and return the hash. 60859d1ed5bSDimitry Andric llvm::MD5::MD5Result Result; 60959d1ed5bSDimitry Andric MD5.final(Result); 61059d1ed5bSDimitry Andric using namespace llvm::support; 61159d1ed5bSDimitry Andric return endian::read<uint64_t, little, unaligned>(Result); 61259d1ed5bSDimitry Andric } 61359d1ed5bSDimitry Andric 6140623d748SDimitry Andric void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) { 6150623d748SDimitry Andric const Decl *D = GD.getDecl(); 616e7145dcbSDimitry Andric bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr(); 61759d1ed5bSDimitry Andric llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader(); 61859d1ed5bSDimitry Andric if (!InstrumentRegions && !PGOReader) 61959d1ed5bSDimitry Andric return; 62059d1ed5bSDimitry Andric if (D->isImplicit()) 62159d1ed5bSDimitry Andric return; 6220623d748SDimitry Andric // Constructors and destructors may be represented by several functions in IR. 6230623d748SDimitry Andric // If so, instrument only base variant, others are implemented by delegation 6240623d748SDimitry Andric // to the base one, it would be counted twice otherwise. 6250623d748SDimitry Andric if (CGM.getTarget().getCXXABI().hasConstructorVariants() && 6260623d748SDimitry Andric ((isa<CXXConstructorDecl>(GD.getDecl()) && 6270623d748SDimitry Andric GD.getCtorType() != Ctor_Base) || 6280623d748SDimitry Andric (isa<CXXDestructorDecl>(GD.getDecl()) && 6290623d748SDimitry Andric GD.getDtorType() != Dtor_Base))) { 6300623d748SDimitry Andric return; 6310623d748SDimitry Andric } 63239d628a0SDimitry Andric CGM.ClearUnusedCoverageMapping(D); 63359d1ed5bSDimitry Andric setFuncName(Fn); 63459d1ed5bSDimitry Andric 63559d1ed5bSDimitry Andric mapRegionCounters(D); 63639d628a0SDimitry Andric if (CGM.getCodeGenOpts().CoverageMapping) 63739d628a0SDimitry Andric emitCounterRegionMapping(D); 63859d1ed5bSDimitry Andric if (PGOReader) { 63959d1ed5bSDimitry Andric SourceManager &SM = CGM.getContext().getSourceManager(); 64059d1ed5bSDimitry Andric loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation())); 64159d1ed5bSDimitry Andric computeRegionCounts(D); 64259d1ed5bSDimitry Andric applyFunctionAttributes(PGOReader, Fn); 64359d1ed5bSDimitry Andric } 64459d1ed5bSDimitry Andric } 64559d1ed5bSDimitry Andric 64659d1ed5bSDimitry Andric void CodeGenPGO::mapRegionCounters(const Decl *D) { 64759d1ed5bSDimitry Andric RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>); 64859d1ed5bSDimitry Andric MapRegionCounters Walker(*RegionCounterMap); 64959d1ed5bSDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) 65059d1ed5bSDimitry Andric Walker.TraverseDecl(const_cast<FunctionDecl *>(FD)); 65159d1ed5bSDimitry Andric else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 65259d1ed5bSDimitry Andric Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD)); 65359d1ed5bSDimitry Andric else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D)) 65459d1ed5bSDimitry Andric Walker.TraverseDecl(const_cast<BlockDecl *>(BD)); 65559d1ed5bSDimitry Andric else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D)) 65659d1ed5bSDimitry Andric Walker.TraverseDecl(const_cast<CapturedDecl *>(CD)); 65759d1ed5bSDimitry Andric assert(Walker.NextCounter > 0 && "no entry counter mapped for decl"); 65859d1ed5bSDimitry Andric NumRegionCounters = Walker.NextCounter; 65959d1ed5bSDimitry Andric FunctionHash = Walker.Hash.finalize(); 66059d1ed5bSDimitry Andric } 66159d1ed5bSDimitry Andric 662e7145dcbSDimitry Andric bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) { 66339d628a0SDimitry Andric if (SkipCoverageMapping) 664e7145dcbSDimitry Andric return true; 665e7145dcbSDimitry Andric 666e7145dcbSDimitry Andric // Don't map the functions in system headers. 667e7145dcbSDimitry Andric const auto &SM = CGM.getContext().getSourceManager(); 66839d628a0SDimitry Andric auto Loc = D->getBody()->getLocStart(); 669e7145dcbSDimitry Andric return SM.isInSystemHeader(Loc); 670e7145dcbSDimitry Andric } 671e7145dcbSDimitry Andric 672e7145dcbSDimitry Andric void CodeGenPGO::emitCounterRegionMapping(const Decl *D) { 673e7145dcbSDimitry Andric if (skipRegionMappingForDecl(D)) 67439d628a0SDimitry Andric return; 67539d628a0SDimitry Andric 67639d628a0SDimitry Andric std::string CoverageMapping; 67739d628a0SDimitry Andric llvm::raw_string_ostream OS(CoverageMapping); 67839d628a0SDimitry Andric CoverageMappingGen MappingGen(*CGM.getCoverageMapping(), 67939d628a0SDimitry Andric CGM.getContext().getSourceManager(), 68039d628a0SDimitry Andric CGM.getLangOpts(), RegionCounterMap.get()); 68139d628a0SDimitry Andric MappingGen.emitCounterMapping(D, OS); 68239d628a0SDimitry Andric OS.flush(); 68339d628a0SDimitry Andric 68439d628a0SDimitry Andric if (CoverageMapping.empty()) 68539d628a0SDimitry Andric return; 68639d628a0SDimitry Andric 68739d628a0SDimitry Andric CGM.getCoverageMapping()->addFunctionMappingRecord( 68839d628a0SDimitry Andric FuncNameVar, FuncName, FunctionHash, CoverageMapping); 68939d628a0SDimitry Andric } 69039d628a0SDimitry Andric 69139d628a0SDimitry Andric void 69233956c43SDimitry Andric CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef Name, 69339d628a0SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage) { 694e7145dcbSDimitry Andric if (skipRegionMappingForDecl(D)) 69539d628a0SDimitry Andric return; 69639d628a0SDimitry Andric 69739d628a0SDimitry Andric std::string CoverageMapping; 69839d628a0SDimitry Andric llvm::raw_string_ostream OS(CoverageMapping); 69939d628a0SDimitry Andric CoverageMappingGen MappingGen(*CGM.getCoverageMapping(), 70039d628a0SDimitry Andric CGM.getContext().getSourceManager(), 70139d628a0SDimitry Andric CGM.getLangOpts()); 70239d628a0SDimitry Andric MappingGen.emitEmptyMapping(D, OS); 70339d628a0SDimitry Andric OS.flush(); 70439d628a0SDimitry Andric 70539d628a0SDimitry Andric if (CoverageMapping.empty()) 70639d628a0SDimitry Andric return; 70739d628a0SDimitry Andric 70833956c43SDimitry Andric setFuncName(Name, Linkage); 70939d628a0SDimitry Andric CGM.getCoverageMapping()->addFunctionMappingRecord( 710444ed5c5SDimitry Andric FuncNameVar, FuncName, FunctionHash, CoverageMapping, false); 71139d628a0SDimitry Andric } 71239d628a0SDimitry Andric 71359d1ed5bSDimitry Andric void CodeGenPGO::computeRegionCounts(const Decl *D) { 71459d1ed5bSDimitry Andric StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>); 71559d1ed5bSDimitry Andric ComputeRegionCounts Walker(*StmtCountMap, *this); 71659d1ed5bSDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) 71759d1ed5bSDimitry Andric Walker.VisitFunctionDecl(FD); 71859d1ed5bSDimitry Andric else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 71959d1ed5bSDimitry Andric Walker.VisitObjCMethodDecl(MD); 72059d1ed5bSDimitry Andric else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D)) 72159d1ed5bSDimitry Andric Walker.VisitBlockDecl(BD); 72259d1ed5bSDimitry Andric else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D)) 72359d1ed5bSDimitry Andric Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD)); 72459d1ed5bSDimitry Andric } 72559d1ed5bSDimitry Andric 72659d1ed5bSDimitry Andric void 72759d1ed5bSDimitry Andric CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader, 72859d1ed5bSDimitry Andric llvm::Function *Fn) { 72959d1ed5bSDimitry Andric if (!haveRegionCounts()) 73059d1ed5bSDimitry Andric return; 73159d1ed5bSDimitry Andric 7320623d748SDimitry Andric uint64_t FunctionCount = getRegionCount(nullptr); 73397bc6c73SDimitry Andric Fn->setEntryCount(FunctionCount); 73459d1ed5bSDimitry Andric } 73559d1ed5bSDimitry Andric 73633956c43SDimitry Andric void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S) { 737e7145dcbSDimitry Andric if (!CGM.getCodeGenOpts().hasProfileClangInstr() || !RegionCounterMap) 73859d1ed5bSDimitry Andric return; 7390623d748SDimitry Andric if (!Builder.GetInsertBlock()) 74039d628a0SDimitry Andric return; 74133956c43SDimitry Andric 74233956c43SDimitry Andric unsigned Counter = (*RegionCounterMap)[S]; 74339d628a0SDimitry Andric auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 74433956c43SDimitry Andric Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment), 74533956c43SDimitry Andric {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy), 74639d628a0SDimitry Andric Builder.getInt64(FunctionHash), 74739d628a0SDimitry Andric Builder.getInt32(NumRegionCounters), 74833956c43SDimitry Andric Builder.getInt32(Counter)}); 74959d1ed5bSDimitry Andric } 75059d1ed5bSDimitry Andric 751e7145dcbSDimitry Andric // This method either inserts a call to the profile run-time during 752e7145dcbSDimitry Andric // instrumentation or puts profile data into metadata for PGO use. 753e7145dcbSDimitry Andric void CodeGenPGO::valueProfile(CGBuilderTy &Builder, uint32_t ValueKind, 754e7145dcbSDimitry Andric llvm::Instruction *ValueSite, llvm::Value *ValuePtr) { 755e7145dcbSDimitry Andric 756e7145dcbSDimitry Andric if (!EnableValueProfiling) 757e7145dcbSDimitry Andric return; 758e7145dcbSDimitry Andric 759e7145dcbSDimitry Andric if (!ValuePtr || !ValueSite || !Builder.GetInsertBlock()) 760e7145dcbSDimitry Andric return; 761e7145dcbSDimitry Andric 762e7145dcbSDimitry Andric if (isa<llvm::Constant>(ValuePtr)) 763e7145dcbSDimitry Andric return; 764e7145dcbSDimitry Andric 765e7145dcbSDimitry Andric bool InstrumentValueSites = CGM.getCodeGenOpts().hasProfileClangInstr(); 766e7145dcbSDimitry Andric if (InstrumentValueSites && RegionCounterMap) { 767e7145dcbSDimitry Andric auto BuilderInsertPoint = Builder.saveIP(); 768e7145dcbSDimitry Andric Builder.SetInsertPoint(ValueSite); 769e7145dcbSDimitry Andric llvm::Value *Args[5] = { 770e7145dcbSDimitry Andric llvm::ConstantExpr::getBitCast(FuncNameVar, Builder.getInt8PtrTy()), 771e7145dcbSDimitry Andric Builder.getInt64(FunctionHash), 772e7145dcbSDimitry Andric Builder.CreatePtrToInt(ValuePtr, Builder.getInt64Ty()), 773e7145dcbSDimitry Andric Builder.getInt32(ValueKind), 774e7145dcbSDimitry Andric Builder.getInt32(NumValueSites[ValueKind]++) 775e7145dcbSDimitry Andric }; 776e7145dcbSDimitry Andric Builder.CreateCall( 777e7145dcbSDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::instrprof_value_profile), Args); 778e7145dcbSDimitry Andric Builder.restoreIP(BuilderInsertPoint); 779e7145dcbSDimitry Andric return; 780e7145dcbSDimitry Andric } 781e7145dcbSDimitry Andric 782e7145dcbSDimitry Andric llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader(); 783e7145dcbSDimitry Andric if (PGOReader && haveRegionCounts()) { 784e7145dcbSDimitry Andric // We record the top most called three functions at each call site. 785e7145dcbSDimitry Andric // Profile metadata contains "VP" string identifying this metadata 786e7145dcbSDimitry Andric // as value profiling data, then a uint32_t value for the value profiling 787e7145dcbSDimitry Andric // kind, a uint64_t value for the total number of times the call is 788e7145dcbSDimitry Andric // executed, followed by the function hash and execution count (uint64_t) 789e7145dcbSDimitry Andric // pairs for each function. 790e7145dcbSDimitry Andric if (NumValueSites[ValueKind] >= ProfRecord->getNumValueSites(ValueKind)) 791e7145dcbSDimitry Andric return; 792e7145dcbSDimitry Andric 793e7145dcbSDimitry Andric llvm::annotateValueSite(CGM.getModule(), *ValueSite, *ProfRecord, 794e7145dcbSDimitry Andric (llvm::InstrProfValueKind)ValueKind, 795e7145dcbSDimitry Andric NumValueSites[ValueKind]); 796e7145dcbSDimitry Andric 797e7145dcbSDimitry Andric NumValueSites[ValueKind]++; 798e7145dcbSDimitry Andric } 799e7145dcbSDimitry Andric } 800e7145dcbSDimitry Andric 80159d1ed5bSDimitry Andric void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader, 80259d1ed5bSDimitry Andric bool IsInMainFile) { 80359d1ed5bSDimitry Andric CGM.getPGOStats().addVisited(IsInMainFile); 80439d628a0SDimitry Andric RegionCounts.clear(); 805e7145dcbSDimitry Andric llvm::Expected<llvm::InstrProfRecord> RecordExpected = 806e7145dcbSDimitry Andric PGOReader->getInstrProfRecord(FuncName, FunctionHash); 807e7145dcbSDimitry Andric if (auto E = RecordExpected.takeError()) { 808e7145dcbSDimitry Andric auto IPE = llvm::InstrProfError::take(std::move(E)); 809e7145dcbSDimitry Andric if (IPE == llvm::instrprof_error::unknown_function) 81059d1ed5bSDimitry Andric CGM.getPGOStats().addMissing(IsInMainFile); 811e7145dcbSDimitry Andric else if (IPE == llvm::instrprof_error::hash_mismatch) 81259d1ed5bSDimitry Andric CGM.getPGOStats().addMismatched(IsInMainFile); 813e7145dcbSDimitry Andric else if (IPE == llvm::instrprof_error::malformed) 81439d628a0SDimitry Andric // TODO: Consider a more specific warning for this case. 81539d628a0SDimitry Andric CGM.getPGOStats().addMismatched(IsInMainFile); 816e7145dcbSDimitry Andric return; 81759d1ed5bSDimitry Andric } 818e7145dcbSDimitry Andric ProfRecord = 819e7145dcbSDimitry Andric llvm::make_unique<llvm::InstrProfRecord>(std::move(RecordExpected.get())); 820e7145dcbSDimitry Andric RegionCounts = ProfRecord->Counts; 82159d1ed5bSDimitry Andric } 82259d1ed5bSDimitry Andric 82359d1ed5bSDimitry Andric /// \brief Calculate what to divide by to scale weights. 82459d1ed5bSDimitry Andric /// 82559d1ed5bSDimitry Andric /// Given the maximum weight, calculate a divisor that will scale all the 82659d1ed5bSDimitry Andric /// weights to strictly less than UINT32_MAX. 82759d1ed5bSDimitry Andric static uint64_t calculateWeightScale(uint64_t MaxWeight) { 82859d1ed5bSDimitry Andric return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1; 82959d1ed5bSDimitry Andric } 83059d1ed5bSDimitry Andric 83159d1ed5bSDimitry Andric /// \brief Scale an individual branch weight (and add 1). 83259d1ed5bSDimitry Andric /// 83359d1ed5bSDimitry Andric /// Scale a 64-bit weight down to 32-bits using \c Scale. 83459d1ed5bSDimitry Andric /// 83559d1ed5bSDimitry Andric /// According to Laplace's Rule of Succession, it is better to compute the 83659d1ed5bSDimitry Andric /// weight based on the count plus 1, so universally add 1 to the value. 83759d1ed5bSDimitry Andric /// 83859d1ed5bSDimitry Andric /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no 83959d1ed5bSDimitry Andric /// greater than \c Weight. 84059d1ed5bSDimitry Andric static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) { 84159d1ed5bSDimitry Andric assert(Scale && "scale by 0?"); 84259d1ed5bSDimitry Andric uint64_t Scaled = Weight / Scale + 1; 84359d1ed5bSDimitry Andric assert(Scaled <= UINT32_MAX && "overflow 32-bits"); 84459d1ed5bSDimitry Andric return Scaled; 84559d1ed5bSDimitry Andric } 84659d1ed5bSDimitry Andric 84733956c43SDimitry Andric llvm::MDNode *CodeGenFunction::createProfileWeights(uint64_t TrueCount, 84859d1ed5bSDimitry Andric uint64_t FalseCount) { 84959d1ed5bSDimitry Andric // Check for empty weights. 85059d1ed5bSDimitry Andric if (!TrueCount && !FalseCount) 85159d1ed5bSDimitry Andric return nullptr; 85259d1ed5bSDimitry Andric 85359d1ed5bSDimitry Andric // Calculate how to scale down to 32-bits. 85459d1ed5bSDimitry Andric uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount)); 85559d1ed5bSDimitry Andric 85659d1ed5bSDimitry Andric llvm::MDBuilder MDHelper(CGM.getLLVMContext()); 85759d1ed5bSDimitry Andric return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale), 85859d1ed5bSDimitry Andric scaleBranchWeight(FalseCount, Scale)); 85959d1ed5bSDimitry Andric } 86059d1ed5bSDimitry Andric 86133956c43SDimitry Andric llvm::MDNode * 86233956c43SDimitry Andric CodeGenFunction::createProfileWeights(ArrayRef<uint64_t> Weights) { 86359d1ed5bSDimitry Andric // We need at least two elements to create meaningful weights. 86459d1ed5bSDimitry Andric if (Weights.size() < 2) 86559d1ed5bSDimitry Andric return nullptr; 86659d1ed5bSDimitry Andric 86759d1ed5bSDimitry Andric // Check for empty weights. 86859d1ed5bSDimitry Andric uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end()); 86959d1ed5bSDimitry Andric if (MaxWeight == 0) 87059d1ed5bSDimitry Andric return nullptr; 87159d1ed5bSDimitry Andric 87259d1ed5bSDimitry Andric // Calculate how to scale down to 32-bits. 87359d1ed5bSDimitry Andric uint64_t Scale = calculateWeightScale(MaxWeight); 87459d1ed5bSDimitry Andric 87559d1ed5bSDimitry Andric SmallVector<uint32_t, 16> ScaledWeights; 87659d1ed5bSDimitry Andric ScaledWeights.reserve(Weights.size()); 87759d1ed5bSDimitry Andric for (uint64_t W : Weights) 87859d1ed5bSDimitry Andric ScaledWeights.push_back(scaleBranchWeight(W, Scale)); 87959d1ed5bSDimitry Andric 88059d1ed5bSDimitry Andric llvm::MDBuilder MDHelper(CGM.getLLVMContext()); 88159d1ed5bSDimitry Andric return MDHelper.createBranchWeights(ScaledWeights); 88259d1ed5bSDimitry Andric } 88359d1ed5bSDimitry Andric 88433956c43SDimitry Andric llvm::MDNode *CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond, 88533956c43SDimitry Andric uint64_t LoopCount) { 88633956c43SDimitry Andric if (!PGO.haveRegionCounts()) 88759d1ed5bSDimitry Andric return nullptr; 88833956c43SDimitry Andric Optional<uint64_t> CondCount = PGO.getStmtCount(Cond); 88933956c43SDimitry Andric assert(CondCount.hasValue() && "missing expected loop condition count"); 89033956c43SDimitry Andric if (*CondCount == 0) 89159d1ed5bSDimitry Andric return nullptr; 89233956c43SDimitry Andric return createProfileWeights(LoopCount, 89333956c43SDimitry Andric std::max(*CondCount, LoopCount) - LoopCount); 89459d1ed5bSDimitry Andric } 895