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) { 310623d748SDimitry Andric llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader(); 320623d748SDimitry Andric FuncName = llvm::getPGOFuncName( 330623d748SDimitry Andric Name, Linkage, CGM.getCodeGenOpts().MainFileName, 340623d748SDimitry Andric PGOReader ? PGOReader->getVersion() : llvm::IndexedInstrProf::Version); 3559d1ed5bSDimitry Andric 3639d628a0SDimitry Andric // If we're generating a profile, create a variable for the name. 3739d628a0SDimitry Andric if (CGM.getCodeGenOpts().ProfileInstrGenerate) 380623d748SDimitry Andric FuncNameVar = llvm::createPGOFuncNameVar(CGM.getModule(), Linkage, FuncName); 3959d1ed5bSDimitry Andric } 4059d1ed5bSDimitry Andric 4139d628a0SDimitry Andric void CodeGenPGO::setFuncName(llvm::Function *Fn) { 4239d628a0SDimitry Andric setFuncName(Fn->getName(), Fn->getLinkage()); 4359d1ed5bSDimitry Andric } 4459d1ed5bSDimitry Andric 4559d1ed5bSDimitry Andric namespace { 4659d1ed5bSDimitry Andric /// \brief Stable hasher for PGO region counters. 4759d1ed5bSDimitry Andric /// 4859d1ed5bSDimitry Andric /// PGOHash produces a stable hash of a given function's control flow. 4959d1ed5bSDimitry Andric /// 5059d1ed5bSDimitry Andric /// Changing the output of this hash will invalidate all previously generated 5159d1ed5bSDimitry Andric /// profiles -- i.e., don't do it. 5259d1ed5bSDimitry Andric /// 5359d1ed5bSDimitry Andric /// \note When this hash does eventually change (years?), we still need to 5459d1ed5bSDimitry Andric /// support old hashes. We'll need to pull in the version number from the 5559d1ed5bSDimitry Andric /// profile data format and use the matching hash function. 5659d1ed5bSDimitry Andric class PGOHash { 5759d1ed5bSDimitry Andric uint64_t Working; 5859d1ed5bSDimitry Andric unsigned Count; 5959d1ed5bSDimitry Andric llvm::MD5 MD5; 6059d1ed5bSDimitry Andric 6159d1ed5bSDimitry Andric static const int NumBitsPerType = 6; 6259d1ed5bSDimitry Andric static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType; 6359d1ed5bSDimitry Andric static const unsigned TooBig = 1u << NumBitsPerType; 6459d1ed5bSDimitry Andric 6559d1ed5bSDimitry Andric public: 6659d1ed5bSDimitry Andric /// \brief Hash values for AST nodes. 6759d1ed5bSDimitry Andric /// 6859d1ed5bSDimitry Andric /// Distinct values for AST nodes that have region counters attached. 6959d1ed5bSDimitry Andric /// 7059d1ed5bSDimitry Andric /// These values must be stable. All new members must be added at the end, 7159d1ed5bSDimitry Andric /// and no members should be removed. Changing the enumeration value for an 7259d1ed5bSDimitry Andric /// AST node will affect the hash of every function that contains that node. 7359d1ed5bSDimitry Andric enum HashType : unsigned char { 7459d1ed5bSDimitry Andric None = 0, 7559d1ed5bSDimitry Andric LabelStmt = 1, 7659d1ed5bSDimitry Andric WhileStmt, 7759d1ed5bSDimitry Andric DoStmt, 7859d1ed5bSDimitry Andric ForStmt, 7959d1ed5bSDimitry Andric CXXForRangeStmt, 8059d1ed5bSDimitry Andric ObjCForCollectionStmt, 8159d1ed5bSDimitry Andric SwitchStmt, 8259d1ed5bSDimitry Andric CaseStmt, 8359d1ed5bSDimitry Andric DefaultStmt, 8459d1ed5bSDimitry Andric IfStmt, 8559d1ed5bSDimitry Andric CXXTryStmt, 8659d1ed5bSDimitry Andric CXXCatchStmt, 8759d1ed5bSDimitry Andric ConditionalOperator, 8859d1ed5bSDimitry Andric BinaryOperatorLAnd, 8959d1ed5bSDimitry Andric BinaryOperatorLOr, 9059d1ed5bSDimitry Andric BinaryConditionalOperator, 9159d1ed5bSDimitry Andric 9259d1ed5bSDimitry Andric // Keep this last. It's for the static assert that follows. 9359d1ed5bSDimitry Andric LastHashType 9459d1ed5bSDimitry Andric }; 9559d1ed5bSDimitry Andric static_assert(LastHashType <= TooBig, "Too many types in HashType"); 9659d1ed5bSDimitry Andric 9759d1ed5bSDimitry Andric // TODO: When this format changes, take in a version number here, and use the 9859d1ed5bSDimitry Andric // old hash calculation for file formats that used the old hash. 9959d1ed5bSDimitry Andric PGOHash() : Working(0), Count(0) {} 10059d1ed5bSDimitry Andric void combine(HashType Type); 10159d1ed5bSDimitry Andric uint64_t finalize(); 10259d1ed5bSDimitry Andric }; 10359d1ed5bSDimitry Andric const int PGOHash::NumBitsPerType; 10459d1ed5bSDimitry Andric const unsigned PGOHash::NumTypesPerWord; 10559d1ed5bSDimitry Andric const unsigned PGOHash::TooBig; 10659d1ed5bSDimitry Andric 10759d1ed5bSDimitry Andric /// A RecursiveASTVisitor that fills a map of statements to PGO counters. 10859d1ed5bSDimitry Andric struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> { 10959d1ed5bSDimitry Andric /// The next counter value to assign. 11059d1ed5bSDimitry Andric unsigned NextCounter; 11159d1ed5bSDimitry Andric /// The function hash. 11259d1ed5bSDimitry Andric PGOHash Hash; 11359d1ed5bSDimitry Andric /// The map of statements to counters. 11459d1ed5bSDimitry Andric llvm::DenseMap<const Stmt *, unsigned> &CounterMap; 11559d1ed5bSDimitry Andric 11659d1ed5bSDimitry Andric MapRegionCounters(llvm::DenseMap<const Stmt *, unsigned> &CounterMap) 11759d1ed5bSDimitry Andric : NextCounter(0), CounterMap(CounterMap) {} 11859d1ed5bSDimitry Andric 11959d1ed5bSDimitry Andric // Blocks and lambdas are handled as separate functions, so we need not 12059d1ed5bSDimitry Andric // traverse them in the parent context. 12159d1ed5bSDimitry Andric bool TraverseBlockExpr(BlockExpr *BE) { return true; } 12259d1ed5bSDimitry Andric bool TraverseLambdaBody(LambdaExpr *LE) { return true; } 12359d1ed5bSDimitry Andric bool TraverseCapturedStmt(CapturedStmt *CS) { return true; } 12459d1ed5bSDimitry Andric 12559d1ed5bSDimitry Andric bool VisitDecl(const Decl *D) { 12659d1ed5bSDimitry Andric switch (D->getKind()) { 12759d1ed5bSDimitry Andric default: 12859d1ed5bSDimitry Andric break; 12959d1ed5bSDimitry Andric case Decl::Function: 13059d1ed5bSDimitry Andric case Decl::CXXMethod: 13159d1ed5bSDimitry Andric case Decl::CXXConstructor: 13259d1ed5bSDimitry Andric case Decl::CXXDestructor: 13359d1ed5bSDimitry Andric case Decl::CXXConversion: 13459d1ed5bSDimitry Andric case Decl::ObjCMethod: 13559d1ed5bSDimitry Andric case Decl::Block: 13659d1ed5bSDimitry Andric case Decl::Captured: 13759d1ed5bSDimitry Andric CounterMap[D->getBody()] = NextCounter++; 13859d1ed5bSDimitry Andric break; 13959d1ed5bSDimitry Andric } 14059d1ed5bSDimitry Andric return true; 14159d1ed5bSDimitry Andric } 14259d1ed5bSDimitry Andric 14359d1ed5bSDimitry Andric bool VisitStmt(const Stmt *S) { 14459d1ed5bSDimitry Andric auto Type = getHashType(S); 14559d1ed5bSDimitry Andric if (Type == PGOHash::None) 14659d1ed5bSDimitry Andric return true; 14759d1ed5bSDimitry Andric 14859d1ed5bSDimitry Andric CounterMap[S] = NextCounter++; 14959d1ed5bSDimitry Andric Hash.combine(Type); 15059d1ed5bSDimitry Andric return true; 15159d1ed5bSDimitry Andric } 15259d1ed5bSDimitry Andric PGOHash::HashType getHashType(const Stmt *S) { 15359d1ed5bSDimitry Andric switch (S->getStmtClass()) { 15459d1ed5bSDimitry Andric default: 15559d1ed5bSDimitry Andric break; 15659d1ed5bSDimitry Andric case Stmt::LabelStmtClass: 15759d1ed5bSDimitry Andric return PGOHash::LabelStmt; 15859d1ed5bSDimitry Andric case Stmt::WhileStmtClass: 15959d1ed5bSDimitry Andric return PGOHash::WhileStmt; 16059d1ed5bSDimitry Andric case Stmt::DoStmtClass: 16159d1ed5bSDimitry Andric return PGOHash::DoStmt; 16259d1ed5bSDimitry Andric case Stmt::ForStmtClass: 16359d1ed5bSDimitry Andric return PGOHash::ForStmt; 16459d1ed5bSDimitry Andric case Stmt::CXXForRangeStmtClass: 16559d1ed5bSDimitry Andric return PGOHash::CXXForRangeStmt; 16659d1ed5bSDimitry Andric case Stmt::ObjCForCollectionStmtClass: 16759d1ed5bSDimitry Andric return PGOHash::ObjCForCollectionStmt; 16859d1ed5bSDimitry Andric case Stmt::SwitchStmtClass: 16959d1ed5bSDimitry Andric return PGOHash::SwitchStmt; 17059d1ed5bSDimitry Andric case Stmt::CaseStmtClass: 17159d1ed5bSDimitry Andric return PGOHash::CaseStmt; 17259d1ed5bSDimitry Andric case Stmt::DefaultStmtClass: 17359d1ed5bSDimitry Andric return PGOHash::DefaultStmt; 17459d1ed5bSDimitry Andric case Stmt::IfStmtClass: 17559d1ed5bSDimitry Andric return PGOHash::IfStmt; 17659d1ed5bSDimitry Andric case Stmt::CXXTryStmtClass: 17759d1ed5bSDimitry Andric return PGOHash::CXXTryStmt; 17859d1ed5bSDimitry Andric case Stmt::CXXCatchStmtClass: 17959d1ed5bSDimitry Andric return PGOHash::CXXCatchStmt; 18059d1ed5bSDimitry Andric case Stmt::ConditionalOperatorClass: 18159d1ed5bSDimitry Andric return PGOHash::ConditionalOperator; 18259d1ed5bSDimitry Andric case Stmt::BinaryConditionalOperatorClass: 18359d1ed5bSDimitry Andric return PGOHash::BinaryConditionalOperator; 18459d1ed5bSDimitry Andric case Stmt::BinaryOperatorClass: { 18559d1ed5bSDimitry Andric const BinaryOperator *BO = cast<BinaryOperator>(S); 18659d1ed5bSDimitry Andric if (BO->getOpcode() == BO_LAnd) 18759d1ed5bSDimitry Andric return PGOHash::BinaryOperatorLAnd; 18859d1ed5bSDimitry Andric if (BO->getOpcode() == BO_LOr) 18959d1ed5bSDimitry Andric return PGOHash::BinaryOperatorLOr; 19059d1ed5bSDimitry Andric break; 19159d1ed5bSDimitry Andric } 19259d1ed5bSDimitry Andric } 19359d1ed5bSDimitry Andric return PGOHash::None; 19459d1ed5bSDimitry Andric } 19559d1ed5bSDimitry Andric }; 19659d1ed5bSDimitry Andric 19759d1ed5bSDimitry Andric /// A StmtVisitor that propagates the raw counts through the AST and 19859d1ed5bSDimitry Andric /// records the count at statements where the value may change. 19959d1ed5bSDimitry Andric struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> { 20059d1ed5bSDimitry Andric /// PGO state. 20159d1ed5bSDimitry Andric CodeGenPGO &PGO; 20259d1ed5bSDimitry Andric 20359d1ed5bSDimitry Andric /// A flag that is set when the current count should be recorded on the 20459d1ed5bSDimitry Andric /// next statement, such as at the exit of a loop. 20559d1ed5bSDimitry Andric bool RecordNextStmtCount; 20659d1ed5bSDimitry Andric 20733956c43SDimitry Andric /// The count at the current location in the traversal. 20833956c43SDimitry Andric uint64_t CurrentCount; 20933956c43SDimitry Andric 21059d1ed5bSDimitry Andric /// The map of statements to count values. 21159d1ed5bSDimitry Andric llvm::DenseMap<const Stmt *, uint64_t> &CountMap; 21259d1ed5bSDimitry Andric 21359d1ed5bSDimitry Andric /// BreakContinueStack - Keep counts of breaks and continues inside loops. 21459d1ed5bSDimitry Andric struct BreakContinue { 21559d1ed5bSDimitry Andric uint64_t BreakCount; 21659d1ed5bSDimitry Andric uint64_t ContinueCount; 21759d1ed5bSDimitry Andric BreakContinue() : BreakCount(0), ContinueCount(0) {} 21859d1ed5bSDimitry Andric }; 21959d1ed5bSDimitry Andric SmallVector<BreakContinue, 8> BreakContinueStack; 22059d1ed5bSDimitry Andric 22159d1ed5bSDimitry Andric ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap, 22259d1ed5bSDimitry Andric CodeGenPGO &PGO) 22359d1ed5bSDimitry Andric : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {} 22459d1ed5bSDimitry Andric 22559d1ed5bSDimitry Andric void RecordStmtCount(const Stmt *S) { 22659d1ed5bSDimitry Andric if (RecordNextStmtCount) { 22733956c43SDimitry Andric CountMap[S] = CurrentCount; 22859d1ed5bSDimitry Andric RecordNextStmtCount = false; 22959d1ed5bSDimitry Andric } 23059d1ed5bSDimitry Andric } 23159d1ed5bSDimitry Andric 23233956c43SDimitry Andric /// Set and return the current count. 23333956c43SDimitry Andric uint64_t setCount(uint64_t Count) { 23433956c43SDimitry Andric CurrentCount = Count; 23533956c43SDimitry Andric return Count; 23633956c43SDimitry Andric } 23733956c43SDimitry Andric 23859d1ed5bSDimitry Andric void VisitStmt(const Stmt *S) { 23959d1ed5bSDimitry Andric RecordStmtCount(S); 2403dac3a9bSDimitry Andric for (const Stmt *Child : S->children()) 2413dac3a9bSDimitry Andric if (Child) 2423dac3a9bSDimitry Andric this->Visit(Child); 24359d1ed5bSDimitry Andric } 24459d1ed5bSDimitry Andric 24559d1ed5bSDimitry Andric void VisitFunctionDecl(const FunctionDecl *D) { 24659d1ed5bSDimitry Andric // Counter tracks entry to the function body. 24733956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody())); 24833956c43SDimitry Andric CountMap[D->getBody()] = BodyCount; 24959d1ed5bSDimitry Andric Visit(D->getBody()); 25059d1ed5bSDimitry Andric } 25159d1ed5bSDimitry Andric 25259d1ed5bSDimitry Andric // Skip lambda expressions. We visit these as FunctionDecls when we're 25359d1ed5bSDimitry Andric // generating them and aren't interested in the body when generating a 25459d1ed5bSDimitry Andric // parent context. 25559d1ed5bSDimitry Andric void VisitLambdaExpr(const LambdaExpr *LE) {} 25659d1ed5bSDimitry Andric 25759d1ed5bSDimitry Andric void VisitCapturedDecl(const CapturedDecl *D) { 25859d1ed5bSDimitry Andric // Counter tracks entry to the capture body. 25933956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody())); 26033956c43SDimitry Andric CountMap[D->getBody()] = BodyCount; 26159d1ed5bSDimitry Andric Visit(D->getBody()); 26259d1ed5bSDimitry Andric } 26359d1ed5bSDimitry Andric 26459d1ed5bSDimitry Andric void VisitObjCMethodDecl(const ObjCMethodDecl *D) { 26559d1ed5bSDimitry Andric // Counter tracks entry to the method body. 26633956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody())); 26733956c43SDimitry Andric CountMap[D->getBody()] = BodyCount; 26859d1ed5bSDimitry Andric Visit(D->getBody()); 26959d1ed5bSDimitry Andric } 27059d1ed5bSDimitry Andric 27159d1ed5bSDimitry Andric void VisitBlockDecl(const BlockDecl *D) { 27259d1ed5bSDimitry Andric // Counter tracks entry to the block body. 27333956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(D->getBody())); 27433956c43SDimitry Andric CountMap[D->getBody()] = BodyCount; 27559d1ed5bSDimitry Andric Visit(D->getBody()); 27659d1ed5bSDimitry Andric } 27759d1ed5bSDimitry Andric 27859d1ed5bSDimitry Andric void VisitReturnStmt(const ReturnStmt *S) { 27959d1ed5bSDimitry Andric RecordStmtCount(S); 28059d1ed5bSDimitry Andric if (S->getRetValue()) 28159d1ed5bSDimitry Andric Visit(S->getRetValue()); 28233956c43SDimitry Andric CurrentCount = 0; 28333956c43SDimitry Andric RecordNextStmtCount = true; 28433956c43SDimitry Andric } 28533956c43SDimitry Andric 28633956c43SDimitry Andric void VisitCXXThrowExpr(const CXXThrowExpr *E) { 28733956c43SDimitry Andric RecordStmtCount(E); 28833956c43SDimitry Andric if (E->getSubExpr()) 28933956c43SDimitry Andric Visit(E->getSubExpr()); 29033956c43SDimitry Andric CurrentCount = 0; 29159d1ed5bSDimitry Andric RecordNextStmtCount = true; 29259d1ed5bSDimitry Andric } 29359d1ed5bSDimitry Andric 29459d1ed5bSDimitry Andric void VisitGotoStmt(const GotoStmt *S) { 29559d1ed5bSDimitry Andric RecordStmtCount(S); 29633956c43SDimitry Andric CurrentCount = 0; 29759d1ed5bSDimitry Andric RecordNextStmtCount = true; 29859d1ed5bSDimitry Andric } 29959d1ed5bSDimitry Andric 30059d1ed5bSDimitry Andric void VisitLabelStmt(const LabelStmt *S) { 30159d1ed5bSDimitry Andric RecordNextStmtCount = false; 30259d1ed5bSDimitry Andric // Counter tracks the block following the label. 30333956c43SDimitry Andric uint64_t BlockCount = setCount(PGO.getRegionCount(S)); 30433956c43SDimitry Andric CountMap[S] = BlockCount; 30559d1ed5bSDimitry Andric Visit(S->getSubStmt()); 30659d1ed5bSDimitry Andric } 30759d1ed5bSDimitry Andric 30859d1ed5bSDimitry Andric void VisitBreakStmt(const BreakStmt *S) { 30959d1ed5bSDimitry Andric RecordStmtCount(S); 31059d1ed5bSDimitry Andric assert(!BreakContinueStack.empty() && "break not in a loop or switch!"); 31133956c43SDimitry Andric BreakContinueStack.back().BreakCount += CurrentCount; 31233956c43SDimitry Andric CurrentCount = 0; 31359d1ed5bSDimitry Andric RecordNextStmtCount = true; 31459d1ed5bSDimitry Andric } 31559d1ed5bSDimitry Andric 31659d1ed5bSDimitry Andric void VisitContinueStmt(const ContinueStmt *S) { 31759d1ed5bSDimitry Andric RecordStmtCount(S); 31859d1ed5bSDimitry Andric assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 31933956c43SDimitry Andric BreakContinueStack.back().ContinueCount += CurrentCount; 32033956c43SDimitry Andric CurrentCount = 0; 32159d1ed5bSDimitry Andric RecordNextStmtCount = true; 32259d1ed5bSDimitry Andric } 32359d1ed5bSDimitry Andric 32459d1ed5bSDimitry Andric void VisitWhileStmt(const WhileStmt *S) { 32559d1ed5bSDimitry Andric RecordStmtCount(S); 32633956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 32733956c43SDimitry Andric 32859d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 32959d1ed5bSDimitry Andric // Visit the body region first so the break/continue adjustments can be 33059d1ed5bSDimitry Andric // included when visiting the condition. 33133956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(S)); 33233956c43SDimitry Andric CountMap[S->getBody()] = CurrentCount; 33359d1ed5bSDimitry Andric Visit(S->getBody()); 33433956c43SDimitry Andric uint64_t BackedgeCount = CurrentCount; 33559d1ed5bSDimitry Andric 33659d1ed5bSDimitry Andric // ...then go back and propagate counts through the condition. The count 33759d1ed5bSDimitry Andric // at the start of the condition is the sum of the incoming edges, 33859d1ed5bSDimitry Andric // the backedge from the end of the loop body, and the edges from 33959d1ed5bSDimitry Andric // continue statements. 34059d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 34133956c43SDimitry Andric uint64_t CondCount = 34233956c43SDimitry Andric setCount(ParentCount + BackedgeCount + BC.ContinueCount); 34333956c43SDimitry Andric CountMap[S->getCond()] = CondCount; 34459d1ed5bSDimitry Andric Visit(S->getCond()); 34533956c43SDimitry Andric setCount(BC.BreakCount + CondCount - BodyCount); 34659d1ed5bSDimitry Andric RecordNextStmtCount = true; 34759d1ed5bSDimitry Andric } 34859d1ed5bSDimitry Andric 34959d1ed5bSDimitry Andric void VisitDoStmt(const DoStmt *S) { 35059d1ed5bSDimitry Andric RecordStmtCount(S); 35133956c43SDimitry Andric uint64_t LoopCount = PGO.getRegionCount(S); 35233956c43SDimitry Andric 35359d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 35433956c43SDimitry Andric // The count doesn't include the fallthrough from the parent scope. Add it. 35533956c43SDimitry Andric uint64_t BodyCount = setCount(LoopCount + CurrentCount); 35633956c43SDimitry Andric CountMap[S->getBody()] = BodyCount; 35759d1ed5bSDimitry Andric Visit(S->getBody()); 35833956c43SDimitry Andric uint64_t BackedgeCount = CurrentCount; 35959d1ed5bSDimitry Andric 36059d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 36159d1ed5bSDimitry Andric // The count at the start of the condition is equal to the count at the 36233956c43SDimitry Andric // end of the body, plus any continues. 36333956c43SDimitry Andric uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount); 36433956c43SDimitry Andric CountMap[S->getCond()] = CondCount; 36559d1ed5bSDimitry Andric Visit(S->getCond()); 36633956c43SDimitry Andric setCount(BC.BreakCount + CondCount - LoopCount); 36759d1ed5bSDimitry Andric RecordNextStmtCount = true; 36859d1ed5bSDimitry Andric } 36959d1ed5bSDimitry Andric 37059d1ed5bSDimitry Andric void VisitForStmt(const ForStmt *S) { 37159d1ed5bSDimitry Andric RecordStmtCount(S); 37259d1ed5bSDimitry Andric if (S->getInit()) 37359d1ed5bSDimitry Andric Visit(S->getInit()); 37433956c43SDimitry Andric 37533956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 37633956c43SDimitry Andric 37759d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 37859d1ed5bSDimitry Andric // Visit the body region first. (This is basically the same as a while 37959d1ed5bSDimitry Andric // loop; see further comments in VisitWhileStmt.) 38033956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(S)); 38133956c43SDimitry Andric CountMap[S->getBody()] = BodyCount; 38259d1ed5bSDimitry Andric Visit(S->getBody()); 38333956c43SDimitry Andric uint64_t BackedgeCount = CurrentCount; 38433956c43SDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 38559d1ed5bSDimitry Andric 38659d1ed5bSDimitry Andric // The increment is essentially part of the body but it needs to include 38759d1ed5bSDimitry Andric // the count for all the continue statements. 38859d1ed5bSDimitry Andric if (S->getInc()) { 38933956c43SDimitry Andric uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount); 39033956c43SDimitry Andric CountMap[S->getInc()] = IncCount; 39159d1ed5bSDimitry Andric Visit(S->getInc()); 39259d1ed5bSDimitry Andric } 39359d1ed5bSDimitry Andric 39459d1ed5bSDimitry Andric // ...then go back and propagate counts through the condition. 39533956c43SDimitry Andric uint64_t CondCount = 39633956c43SDimitry Andric setCount(ParentCount + BackedgeCount + BC.ContinueCount); 39759d1ed5bSDimitry Andric if (S->getCond()) { 39833956c43SDimitry Andric CountMap[S->getCond()] = CondCount; 39959d1ed5bSDimitry Andric Visit(S->getCond()); 40059d1ed5bSDimitry Andric } 40133956c43SDimitry Andric setCount(BC.BreakCount + CondCount - BodyCount); 40259d1ed5bSDimitry Andric RecordNextStmtCount = true; 40359d1ed5bSDimitry Andric } 40459d1ed5bSDimitry Andric 40559d1ed5bSDimitry Andric void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { 40659d1ed5bSDimitry Andric RecordStmtCount(S); 40733956c43SDimitry Andric Visit(S->getLoopVarStmt()); 40859d1ed5bSDimitry Andric Visit(S->getRangeStmt()); 40959d1ed5bSDimitry Andric Visit(S->getBeginEndStmt()); 41033956c43SDimitry Andric 41133956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 41259d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 41359d1ed5bSDimitry Andric // Visit the body region first. (This is basically the same as a while 41459d1ed5bSDimitry Andric // loop; see further comments in VisitWhileStmt.) 41533956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(S)); 41633956c43SDimitry Andric CountMap[S->getBody()] = BodyCount; 41759d1ed5bSDimitry Andric Visit(S->getBody()); 41833956c43SDimitry Andric uint64_t BackedgeCount = CurrentCount; 41933956c43SDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 42059d1ed5bSDimitry Andric 42159d1ed5bSDimitry Andric // The increment is essentially part of the body but it needs to include 42259d1ed5bSDimitry Andric // the count for all the continue statements. 42333956c43SDimitry Andric uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount); 42433956c43SDimitry Andric CountMap[S->getInc()] = IncCount; 42559d1ed5bSDimitry Andric Visit(S->getInc()); 42659d1ed5bSDimitry Andric 42759d1ed5bSDimitry Andric // ...then go back and propagate counts through the condition. 42833956c43SDimitry Andric uint64_t CondCount = 42933956c43SDimitry Andric setCount(ParentCount + BackedgeCount + BC.ContinueCount); 43033956c43SDimitry Andric CountMap[S->getCond()] = CondCount; 43159d1ed5bSDimitry Andric Visit(S->getCond()); 43233956c43SDimitry Andric setCount(BC.BreakCount + CondCount - BodyCount); 43359d1ed5bSDimitry Andric RecordNextStmtCount = true; 43459d1ed5bSDimitry Andric } 43559d1ed5bSDimitry Andric 43659d1ed5bSDimitry Andric void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { 43759d1ed5bSDimitry Andric RecordStmtCount(S); 43859d1ed5bSDimitry Andric Visit(S->getElement()); 43933956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 44059d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 44133956c43SDimitry Andric // Counter tracks the body of the loop. 44233956c43SDimitry Andric uint64_t BodyCount = setCount(PGO.getRegionCount(S)); 44333956c43SDimitry Andric CountMap[S->getBody()] = BodyCount; 44459d1ed5bSDimitry Andric Visit(S->getBody()); 44533956c43SDimitry Andric uint64_t BackedgeCount = CurrentCount; 44659d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 44733956c43SDimitry Andric 44833956c43SDimitry Andric setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount - 44933956c43SDimitry Andric BodyCount); 45059d1ed5bSDimitry Andric RecordNextStmtCount = true; 45159d1ed5bSDimitry Andric } 45259d1ed5bSDimitry Andric 45359d1ed5bSDimitry Andric void VisitSwitchStmt(const SwitchStmt *S) { 45459d1ed5bSDimitry Andric RecordStmtCount(S); 45559d1ed5bSDimitry Andric Visit(S->getCond()); 45633956c43SDimitry Andric CurrentCount = 0; 45759d1ed5bSDimitry Andric BreakContinueStack.push_back(BreakContinue()); 45859d1ed5bSDimitry Andric Visit(S->getBody()); 45959d1ed5bSDimitry Andric // If the switch is inside a loop, add the continue counts. 46059d1ed5bSDimitry Andric BreakContinue BC = BreakContinueStack.pop_back_val(); 46159d1ed5bSDimitry Andric if (!BreakContinueStack.empty()) 46259d1ed5bSDimitry Andric BreakContinueStack.back().ContinueCount += BC.ContinueCount; 46359d1ed5bSDimitry Andric // Counter tracks the exit block of the switch. 46433956c43SDimitry Andric setCount(PGO.getRegionCount(S)); 46559d1ed5bSDimitry Andric RecordNextStmtCount = true; 46659d1ed5bSDimitry Andric } 46759d1ed5bSDimitry Andric 46833956c43SDimitry Andric void VisitSwitchCase(const SwitchCase *S) { 46959d1ed5bSDimitry Andric RecordNextStmtCount = false; 47059d1ed5bSDimitry Andric // Counter for this particular case. This counts only jumps from the 47159d1ed5bSDimitry Andric // switch header and does not include fallthrough from the case before 47259d1ed5bSDimitry Andric // this one. 47333956c43SDimitry Andric uint64_t CaseCount = PGO.getRegionCount(S); 47433956c43SDimitry Andric setCount(CurrentCount + CaseCount); 47533956c43SDimitry Andric // We need the count without fallthrough in the mapping, so it's more useful 47633956c43SDimitry Andric // for branch probabilities. 47733956c43SDimitry Andric CountMap[S] = CaseCount; 47859d1ed5bSDimitry Andric RecordNextStmtCount = true; 47959d1ed5bSDimitry Andric Visit(S->getSubStmt()); 48059d1ed5bSDimitry Andric } 48159d1ed5bSDimitry Andric 48259d1ed5bSDimitry Andric void VisitIfStmt(const IfStmt *S) { 48359d1ed5bSDimitry Andric RecordStmtCount(S); 48433956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 48559d1ed5bSDimitry Andric Visit(S->getCond()); 48659d1ed5bSDimitry Andric 48733956c43SDimitry Andric // Counter tracks the "then" part of an if statement. The count for 48833956c43SDimitry Andric // the "else" part, if it exists, will be calculated from this counter. 48933956c43SDimitry Andric uint64_t ThenCount = setCount(PGO.getRegionCount(S)); 49033956c43SDimitry Andric CountMap[S->getThen()] = ThenCount; 49159d1ed5bSDimitry Andric Visit(S->getThen()); 49233956c43SDimitry Andric uint64_t OutCount = CurrentCount; 49359d1ed5bSDimitry Andric 49433956c43SDimitry Andric uint64_t ElseCount = ParentCount - ThenCount; 49559d1ed5bSDimitry Andric if (S->getElse()) { 49633956c43SDimitry Andric setCount(ElseCount); 49733956c43SDimitry Andric CountMap[S->getElse()] = ElseCount; 49859d1ed5bSDimitry Andric Visit(S->getElse()); 49933956c43SDimitry Andric OutCount += CurrentCount; 50033956c43SDimitry Andric } else 50133956c43SDimitry Andric OutCount += ElseCount; 50233956c43SDimitry Andric setCount(OutCount); 50359d1ed5bSDimitry Andric RecordNextStmtCount = true; 50459d1ed5bSDimitry Andric } 50559d1ed5bSDimitry Andric 50659d1ed5bSDimitry Andric void VisitCXXTryStmt(const CXXTryStmt *S) { 50759d1ed5bSDimitry Andric RecordStmtCount(S); 50859d1ed5bSDimitry Andric Visit(S->getTryBlock()); 50959d1ed5bSDimitry Andric for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I) 51059d1ed5bSDimitry Andric Visit(S->getHandler(I)); 51159d1ed5bSDimitry Andric // Counter tracks the continuation block of the try statement. 51233956c43SDimitry Andric setCount(PGO.getRegionCount(S)); 51359d1ed5bSDimitry Andric RecordNextStmtCount = true; 51459d1ed5bSDimitry Andric } 51559d1ed5bSDimitry Andric 51659d1ed5bSDimitry Andric void VisitCXXCatchStmt(const CXXCatchStmt *S) { 51759d1ed5bSDimitry Andric RecordNextStmtCount = false; 51859d1ed5bSDimitry Andric // Counter tracks the catch statement's handler block. 51933956c43SDimitry Andric uint64_t CatchCount = setCount(PGO.getRegionCount(S)); 52033956c43SDimitry Andric CountMap[S] = CatchCount; 52159d1ed5bSDimitry Andric Visit(S->getHandlerBlock()); 52259d1ed5bSDimitry Andric } 52359d1ed5bSDimitry Andric 52433956c43SDimitry Andric void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { 52559d1ed5bSDimitry Andric RecordStmtCount(E); 52633956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 52759d1ed5bSDimitry Andric Visit(E->getCond()); 52859d1ed5bSDimitry Andric 52933956c43SDimitry Andric // Counter tracks the "true" part of a conditional operator. The 53033956c43SDimitry Andric // count in the "false" part will be calculated from this counter. 53133956c43SDimitry Andric uint64_t TrueCount = setCount(PGO.getRegionCount(E)); 53233956c43SDimitry Andric CountMap[E->getTrueExpr()] = TrueCount; 53359d1ed5bSDimitry Andric Visit(E->getTrueExpr()); 53433956c43SDimitry Andric uint64_t OutCount = CurrentCount; 53559d1ed5bSDimitry Andric 53633956c43SDimitry Andric uint64_t FalseCount = setCount(ParentCount - TrueCount); 53733956c43SDimitry Andric CountMap[E->getFalseExpr()] = FalseCount; 53859d1ed5bSDimitry Andric Visit(E->getFalseExpr()); 53933956c43SDimitry Andric OutCount += CurrentCount; 54059d1ed5bSDimitry Andric 54133956c43SDimitry Andric setCount(OutCount); 54259d1ed5bSDimitry Andric RecordNextStmtCount = true; 54359d1ed5bSDimitry Andric } 54459d1ed5bSDimitry Andric 54559d1ed5bSDimitry Andric void VisitBinLAnd(const BinaryOperator *E) { 54659d1ed5bSDimitry Andric RecordStmtCount(E); 54733956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 54859d1ed5bSDimitry Andric Visit(E->getLHS()); 54933956c43SDimitry Andric // Counter tracks the right hand side of a logical and operator. 55033956c43SDimitry Andric uint64_t RHSCount = setCount(PGO.getRegionCount(E)); 55133956c43SDimitry Andric CountMap[E->getRHS()] = RHSCount; 55259d1ed5bSDimitry Andric Visit(E->getRHS()); 55333956c43SDimitry Andric setCount(ParentCount + RHSCount - CurrentCount); 55459d1ed5bSDimitry Andric RecordNextStmtCount = true; 55559d1ed5bSDimitry Andric } 55659d1ed5bSDimitry Andric 55759d1ed5bSDimitry Andric void VisitBinLOr(const BinaryOperator *E) { 55859d1ed5bSDimitry Andric RecordStmtCount(E); 55933956c43SDimitry Andric uint64_t ParentCount = CurrentCount; 56059d1ed5bSDimitry Andric Visit(E->getLHS()); 56133956c43SDimitry Andric // Counter tracks the right hand side of a logical or operator. 56233956c43SDimitry Andric uint64_t RHSCount = setCount(PGO.getRegionCount(E)); 56333956c43SDimitry Andric CountMap[E->getRHS()] = RHSCount; 56459d1ed5bSDimitry Andric Visit(E->getRHS()); 56533956c43SDimitry Andric setCount(ParentCount + RHSCount - CurrentCount); 56659d1ed5bSDimitry Andric RecordNextStmtCount = true; 56759d1ed5bSDimitry Andric } 56859d1ed5bSDimitry Andric }; 5690623d748SDimitry Andric } // end anonymous namespace 57059d1ed5bSDimitry Andric 57159d1ed5bSDimitry Andric void PGOHash::combine(HashType Type) { 57259d1ed5bSDimitry Andric // Check that we never combine 0 and only have six bits. 57359d1ed5bSDimitry Andric assert(Type && "Hash is invalid: unexpected type 0"); 57459d1ed5bSDimitry Andric assert(unsigned(Type) < TooBig && "Hash is invalid: too many types"); 57559d1ed5bSDimitry Andric 57659d1ed5bSDimitry Andric // Pass through MD5 if enough work has built up. 57759d1ed5bSDimitry Andric if (Count && Count % NumTypesPerWord == 0) { 57859d1ed5bSDimitry Andric using namespace llvm::support; 57959d1ed5bSDimitry Andric uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working); 58059d1ed5bSDimitry Andric MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped))); 58159d1ed5bSDimitry Andric Working = 0; 58259d1ed5bSDimitry Andric } 58359d1ed5bSDimitry Andric 58459d1ed5bSDimitry Andric // Accumulate the current type. 58559d1ed5bSDimitry Andric ++Count; 58659d1ed5bSDimitry Andric Working = Working << NumBitsPerType | Type; 58759d1ed5bSDimitry Andric } 58859d1ed5bSDimitry Andric 58959d1ed5bSDimitry Andric uint64_t PGOHash::finalize() { 59059d1ed5bSDimitry Andric // Use Working as the hash directly if we never used MD5. 59159d1ed5bSDimitry Andric if (Count <= NumTypesPerWord) 59259d1ed5bSDimitry Andric // No need to byte swap here, since none of the math was endian-dependent. 59359d1ed5bSDimitry Andric // This number will be byte-swapped as required on endianness transitions, 59459d1ed5bSDimitry Andric // so we will see the same value on the other side. 59559d1ed5bSDimitry Andric return Working; 59659d1ed5bSDimitry Andric 59759d1ed5bSDimitry Andric // Check for remaining work in Working. 59859d1ed5bSDimitry Andric if (Working) 59959d1ed5bSDimitry Andric MD5.update(Working); 60059d1ed5bSDimitry Andric 60159d1ed5bSDimitry Andric // Finalize the MD5 and return the hash. 60259d1ed5bSDimitry Andric llvm::MD5::MD5Result Result; 60359d1ed5bSDimitry Andric MD5.final(Result); 60459d1ed5bSDimitry Andric using namespace llvm::support; 60559d1ed5bSDimitry Andric return endian::read<uint64_t, little, unaligned>(Result); 60659d1ed5bSDimitry Andric } 60759d1ed5bSDimitry Andric 6080623d748SDimitry Andric void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) { 6090623d748SDimitry Andric const Decl *D = GD.getDecl(); 61059d1ed5bSDimitry Andric bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate; 61159d1ed5bSDimitry Andric llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader(); 61259d1ed5bSDimitry Andric if (!InstrumentRegions && !PGOReader) 61359d1ed5bSDimitry Andric return; 61459d1ed5bSDimitry Andric if (D->isImplicit()) 61559d1ed5bSDimitry Andric return; 6160623d748SDimitry Andric // Constructors and destructors may be represented by several functions in IR. 6170623d748SDimitry Andric // If so, instrument only base variant, others are implemented by delegation 6180623d748SDimitry Andric // to the base one, it would be counted twice otherwise. 6190623d748SDimitry Andric if (CGM.getTarget().getCXXABI().hasConstructorVariants() && 6200623d748SDimitry Andric ((isa<CXXConstructorDecl>(GD.getDecl()) && 6210623d748SDimitry Andric GD.getCtorType() != Ctor_Base) || 6220623d748SDimitry Andric (isa<CXXDestructorDecl>(GD.getDecl()) && 6230623d748SDimitry Andric GD.getDtorType() != Dtor_Base))) { 6240623d748SDimitry Andric return; 6250623d748SDimitry Andric } 62639d628a0SDimitry Andric CGM.ClearUnusedCoverageMapping(D); 62759d1ed5bSDimitry Andric setFuncName(Fn); 62859d1ed5bSDimitry Andric 62959d1ed5bSDimitry Andric mapRegionCounters(D); 63039d628a0SDimitry Andric if (CGM.getCodeGenOpts().CoverageMapping) 63139d628a0SDimitry Andric emitCounterRegionMapping(D); 63259d1ed5bSDimitry Andric if (PGOReader) { 63359d1ed5bSDimitry Andric SourceManager &SM = CGM.getContext().getSourceManager(); 63459d1ed5bSDimitry Andric loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation())); 63559d1ed5bSDimitry Andric computeRegionCounts(D); 63659d1ed5bSDimitry Andric applyFunctionAttributes(PGOReader, Fn); 63759d1ed5bSDimitry Andric } 63859d1ed5bSDimitry Andric } 63959d1ed5bSDimitry Andric 64059d1ed5bSDimitry Andric void CodeGenPGO::mapRegionCounters(const Decl *D) { 64159d1ed5bSDimitry Andric RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>); 64259d1ed5bSDimitry Andric MapRegionCounters Walker(*RegionCounterMap); 64359d1ed5bSDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) 64459d1ed5bSDimitry Andric Walker.TraverseDecl(const_cast<FunctionDecl *>(FD)); 64559d1ed5bSDimitry Andric else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 64659d1ed5bSDimitry Andric Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD)); 64759d1ed5bSDimitry Andric else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D)) 64859d1ed5bSDimitry Andric Walker.TraverseDecl(const_cast<BlockDecl *>(BD)); 64959d1ed5bSDimitry Andric else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D)) 65059d1ed5bSDimitry Andric Walker.TraverseDecl(const_cast<CapturedDecl *>(CD)); 65159d1ed5bSDimitry Andric assert(Walker.NextCounter > 0 && "no entry counter mapped for decl"); 65259d1ed5bSDimitry Andric NumRegionCounters = Walker.NextCounter; 65359d1ed5bSDimitry Andric FunctionHash = Walker.Hash.finalize(); 65459d1ed5bSDimitry Andric } 65559d1ed5bSDimitry Andric 65639d628a0SDimitry Andric void CodeGenPGO::emitCounterRegionMapping(const Decl *D) { 65739d628a0SDimitry Andric if (SkipCoverageMapping) 65839d628a0SDimitry Andric return; 65939d628a0SDimitry Andric // Don't map the functions inside the system headers 66039d628a0SDimitry Andric auto Loc = D->getBody()->getLocStart(); 66139d628a0SDimitry Andric if (CGM.getContext().getSourceManager().isInSystemHeader(Loc)) 66239d628a0SDimitry Andric return; 66339d628a0SDimitry Andric 66439d628a0SDimitry Andric std::string CoverageMapping; 66539d628a0SDimitry Andric llvm::raw_string_ostream OS(CoverageMapping); 66639d628a0SDimitry Andric CoverageMappingGen MappingGen(*CGM.getCoverageMapping(), 66739d628a0SDimitry Andric CGM.getContext().getSourceManager(), 66839d628a0SDimitry Andric CGM.getLangOpts(), RegionCounterMap.get()); 66939d628a0SDimitry Andric MappingGen.emitCounterMapping(D, OS); 67039d628a0SDimitry Andric OS.flush(); 67139d628a0SDimitry Andric 67239d628a0SDimitry Andric if (CoverageMapping.empty()) 67339d628a0SDimitry Andric return; 67439d628a0SDimitry Andric 67539d628a0SDimitry Andric CGM.getCoverageMapping()->addFunctionMappingRecord( 67639d628a0SDimitry Andric FuncNameVar, FuncName, FunctionHash, CoverageMapping); 67739d628a0SDimitry Andric } 67839d628a0SDimitry Andric 67939d628a0SDimitry Andric void 68033956c43SDimitry Andric CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef Name, 68139d628a0SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage) { 68239d628a0SDimitry Andric if (SkipCoverageMapping) 68339d628a0SDimitry Andric return; 68439d628a0SDimitry Andric // Don't map the functions inside the system headers 68539d628a0SDimitry Andric auto Loc = D->getBody()->getLocStart(); 68639d628a0SDimitry Andric if (CGM.getContext().getSourceManager().isInSystemHeader(Loc)) 68739d628a0SDimitry Andric return; 68839d628a0SDimitry Andric 68939d628a0SDimitry Andric std::string CoverageMapping; 69039d628a0SDimitry Andric llvm::raw_string_ostream OS(CoverageMapping); 69139d628a0SDimitry Andric CoverageMappingGen MappingGen(*CGM.getCoverageMapping(), 69239d628a0SDimitry Andric CGM.getContext().getSourceManager(), 69339d628a0SDimitry Andric CGM.getLangOpts()); 69439d628a0SDimitry Andric MappingGen.emitEmptyMapping(D, OS); 69539d628a0SDimitry Andric OS.flush(); 69639d628a0SDimitry Andric 69739d628a0SDimitry Andric if (CoverageMapping.empty()) 69839d628a0SDimitry Andric return; 69939d628a0SDimitry Andric 70033956c43SDimitry Andric setFuncName(Name, Linkage); 70139d628a0SDimitry Andric CGM.getCoverageMapping()->addFunctionMappingRecord( 70239d628a0SDimitry Andric FuncNameVar, FuncName, FunctionHash, CoverageMapping); 70339d628a0SDimitry Andric } 70439d628a0SDimitry Andric 70559d1ed5bSDimitry Andric void CodeGenPGO::computeRegionCounts(const Decl *D) { 70659d1ed5bSDimitry Andric StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>); 70759d1ed5bSDimitry Andric ComputeRegionCounts Walker(*StmtCountMap, *this); 70859d1ed5bSDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) 70959d1ed5bSDimitry Andric Walker.VisitFunctionDecl(FD); 71059d1ed5bSDimitry Andric else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 71159d1ed5bSDimitry Andric Walker.VisitObjCMethodDecl(MD); 71259d1ed5bSDimitry Andric else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D)) 71359d1ed5bSDimitry Andric Walker.VisitBlockDecl(BD); 71459d1ed5bSDimitry Andric else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D)) 71559d1ed5bSDimitry Andric Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD)); 71659d1ed5bSDimitry Andric } 71759d1ed5bSDimitry Andric 71859d1ed5bSDimitry Andric void 71959d1ed5bSDimitry Andric CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader, 72059d1ed5bSDimitry Andric llvm::Function *Fn) { 72159d1ed5bSDimitry Andric if (!haveRegionCounts()) 72259d1ed5bSDimitry Andric return; 72359d1ed5bSDimitry Andric 72459d1ed5bSDimitry Andric uint64_t MaxFunctionCount = PGOReader->getMaximumFunctionCount(); 7250623d748SDimitry Andric uint64_t FunctionCount = getRegionCount(nullptr); 72659d1ed5bSDimitry Andric if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount)) 72759d1ed5bSDimitry Andric // Turn on InlineHint attribute for hot functions. 72859d1ed5bSDimitry Andric // FIXME: 30% is from preliminary tuning on SPEC, it may not be optimal. 72959d1ed5bSDimitry Andric Fn->addFnAttr(llvm::Attribute::InlineHint); 73059d1ed5bSDimitry Andric else if (FunctionCount <= (uint64_t)(0.01 * (double)MaxFunctionCount)) 73159d1ed5bSDimitry Andric // Turn on Cold attribute for cold functions. 73259d1ed5bSDimitry Andric // FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal. 73359d1ed5bSDimitry Andric Fn->addFnAttr(llvm::Attribute::Cold); 73497bc6c73SDimitry Andric 73597bc6c73SDimitry Andric Fn->setEntryCount(FunctionCount); 73659d1ed5bSDimitry Andric } 73759d1ed5bSDimitry Andric 73833956c43SDimitry Andric void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S) { 73939d628a0SDimitry Andric if (!CGM.getCodeGenOpts().ProfileInstrGenerate || !RegionCounterMap) 74059d1ed5bSDimitry Andric return; 7410623d748SDimitry Andric if (!Builder.GetInsertBlock()) 74239d628a0SDimitry Andric return; 74333956c43SDimitry Andric 74433956c43SDimitry Andric unsigned Counter = (*RegionCounterMap)[S]; 74539d628a0SDimitry Andric auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 74633956c43SDimitry Andric Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment), 74733956c43SDimitry Andric {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy), 74839d628a0SDimitry Andric Builder.getInt64(FunctionHash), 74939d628a0SDimitry Andric Builder.getInt32(NumRegionCounters), 75033956c43SDimitry Andric Builder.getInt32(Counter)}); 75159d1ed5bSDimitry Andric } 75259d1ed5bSDimitry Andric 75359d1ed5bSDimitry Andric void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader, 75459d1ed5bSDimitry Andric bool IsInMainFile) { 75559d1ed5bSDimitry Andric CGM.getPGOStats().addVisited(IsInMainFile); 75639d628a0SDimitry Andric RegionCounts.clear(); 75739d628a0SDimitry Andric if (std::error_code EC = 75839d628a0SDimitry Andric PGOReader->getFunctionCounts(FuncName, FunctionHash, RegionCounts)) { 75939d628a0SDimitry Andric if (EC == llvm::instrprof_error::unknown_function) 76059d1ed5bSDimitry Andric CGM.getPGOStats().addMissing(IsInMainFile); 76139d628a0SDimitry Andric else if (EC == llvm::instrprof_error::hash_mismatch) 76259d1ed5bSDimitry Andric CGM.getPGOStats().addMismatched(IsInMainFile); 76339d628a0SDimitry Andric else if (EC == llvm::instrprof_error::malformed) 76439d628a0SDimitry Andric // TODO: Consider a more specific warning for this case. 76539d628a0SDimitry Andric CGM.getPGOStats().addMismatched(IsInMainFile); 76639d628a0SDimitry Andric RegionCounts.clear(); 76759d1ed5bSDimitry Andric } 76859d1ed5bSDimitry Andric } 76959d1ed5bSDimitry Andric 77059d1ed5bSDimitry Andric /// \brief Calculate what to divide by to scale weights. 77159d1ed5bSDimitry Andric /// 77259d1ed5bSDimitry Andric /// Given the maximum weight, calculate a divisor that will scale all the 77359d1ed5bSDimitry Andric /// weights to strictly less than UINT32_MAX. 77459d1ed5bSDimitry Andric static uint64_t calculateWeightScale(uint64_t MaxWeight) { 77559d1ed5bSDimitry Andric return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1; 77659d1ed5bSDimitry Andric } 77759d1ed5bSDimitry Andric 77859d1ed5bSDimitry Andric /// \brief Scale an individual branch weight (and add 1). 77959d1ed5bSDimitry Andric /// 78059d1ed5bSDimitry Andric /// Scale a 64-bit weight down to 32-bits using \c Scale. 78159d1ed5bSDimitry Andric /// 78259d1ed5bSDimitry Andric /// According to Laplace's Rule of Succession, it is better to compute the 78359d1ed5bSDimitry Andric /// weight based on the count plus 1, so universally add 1 to the value. 78459d1ed5bSDimitry Andric /// 78559d1ed5bSDimitry Andric /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no 78659d1ed5bSDimitry Andric /// greater than \c Weight. 78759d1ed5bSDimitry Andric static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) { 78859d1ed5bSDimitry Andric assert(Scale && "scale by 0?"); 78959d1ed5bSDimitry Andric uint64_t Scaled = Weight / Scale + 1; 79059d1ed5bSDimitry Andric assert(Scaled <= UINT32_MAX && "overflow 32-bits"); 79159d1ed5bSDimitry Andric return Scaled; 79259d1ed5bSDimitry Andric } 79359d1ed5bSDimitry Andric 79433956c43SDimitry Andric llvm::MDNode *CodeGenFunction::createProfileWeights(uint64_t TrueCount, 79559d1ed5bSDimitry Andric uint64_t FalseCount) { 79659d1ed5bSDimitry Andric // Check for empty weights. 79759d1ed5bSDimitry Andric if (!TrueCount && !FalseCount) 79859d1ed5bSDimitry Andric return nullptr; 79959d1ed5bSDimitry Andric 80059d1ed5bSDimitry Andric // Calculate how to scale down to 32-bits. 80159d1ed5bSDimitry Andric uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount)); 80259d1ed5bSDimitry Andric 80359d1ed5bSDimitry Andric llvm::MDBuilder MDHelper(CGM.getLLVMContext()); 80459d1ed5bSDimitry Andric return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale), 80559d1ed5bSDimitry Andric scaleBranchWeight(FalseCount, Scale)); 80659d1ed5bSDimitry Andric } 80759d1ed5bSDimitry Andric 80833956c43SDimitry Andric llvm::MDNode * 80933956c43SDimitry Andric CodeGenFunction::createProfileWeights(ArrayRef<uint64_t> Weights) { 81059d1ed5bSDimitry Andric // We need at least two elements to create meaningful weights. 81159d1ed5bSDimitry Andric if (Weights.size() < 2) 81259d1ed5bSDimitry Andric return nullptr; 81359d1ed5bSDimitry Andric 81459d1ed5bSDimitry Andric // Check for empty weights. 81559d1ed5bSDimitry Andric uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end()); 81659d1ed5bSDimitry Andric if (MaxWeight == 0) 81759d1ed5bSDimitry Andric return nullptr; 81859d1ed5bSDimitry Andric 81959d1ed5bSDimitry Andric // Calculate how to scale down to 32-bits. 82059d1ed5bSDimitry Andric uint64_t Scale = calculateWeightScale(MaxWeight); 82159d1ed5bSDimitry Andric 82259d1ed5bSDimitry Andric SmallVector<uint32_t, 16> ScaledWeights; 82359d1ed5bSDimitry Andric ScaledWeights.reserve(Weights.size()); 82459d1ed5bSDimitry Andric for (uint64_t W : Weights) 82559d1ed5bSDimitry Andric ScaledWeights.push_back(scaleBranchWeight(W, Scale)); 82659d1ed5bSDimitry Andric 82759d1ed5bSDimitry Andric llvm::MDBuilder MDHelper(CGM.getLLVMContext()); 82859d1ed5bSDimitry Andric return MDHelper.createBranchWeights(ScaledWeights); 82959d1ed5bSDimitry Andric } 83059d1ed5bSDimitry Andric 83133956c43SDimitry Andric llvm::MDNode *CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond, 83233956c43SDimitry Andric uint64_t LoopCount) { 83333956c43SDimitry Andric if (!PGO.haveRegionCounts()) 83459d1ed5bSDimitry Andric return nullptr; 83533956c43SDimitry Andric Optional<uint64_t> CondCount = PGO.getStmtCount(Cond); 83633956c43SDimitry Andric assert(CondCount.hasValue() && "missing expected loop condition count"); 83733956c43SDimitry Andric if (*CondCount == 0) 83859d1ed5bSDimitry Andric return nullptr; 83933956c43SDimitry Andric return createProfileWeights(LoopCount, 84033956c43SDimitry Andric std::max(*CondCount, LoopCount) - LoopCount); 84159d1ed5bSDimitry Andric } 842