1*67e74705SXin Li //===--- CodeGenPGO.h - PGO Instrumentation for LLVM CodeGen ----*- C++ -*-===// 2*67e74705SXin Li // 3*67e74705SXin Li // The LLVM Compiler Infrastructure 4*67e74705SXin Li // 5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source 6*67e74705SXin Li // License. See LICENSE.TXT for details. 7*67e74705SXin Li // 8*67e74705SXin Li //===----------------------------------------------------------------------===// 9*67e74705SXin Li // 10*67e74705SXin Li // Instrumentation-based profile-guided optimization 11*67e74705SXin Li // 12*67e74705SXin Li //===----------------------------------------------------------------------===// 13*67e74705SXin Li 14*67e74705SXin Li #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENPGO_H 15*67e74705SXin Li #define LLVM_CLANG_LIB_CODEGEN_CODEGENPGO_H 16*67e74705SXin Li 17*67e74705SXin Li #include "CGBuilder.h" 18*67e74705SXin Li #include "CodeGenModule.h" 19*67e74705SXin Li #include "CodeGenTypes.h" 20*67e74705SXin Li #include "clang/Frontend/CodeGenOptions.h" 21*67e74705SXin Li #include "llvm/ADT/StringMap.h" 22*67e74705SXin Li #include "llvm/ProfileData/InstrProfReader.h" 23*67e74705SXin Li #include "llvm/Support/MemoryBuffer.h" 24*67e74705SXin Li #include <array> 25*67e74705SXin Li #include <memory> 26*67e74705SXin Li 27*67e74705SXin Li namespace clang { 28*67e74705SXin Li namespace CodeGen { 29*67e74705SXin Li 30*67e74705SXin Li /// Per-function PGO state. 31*67e74705SXin Li class CodeGenPGO { 32*67e74705SXin Li private: 33*67e74705SXin Li CodeGenModule &CGM; 34*67e74705SXin Li std::string FuncName; 35*67e74705SXin Li llvm::GlobalVariable *FuncNameVar; 36*67e74705SXin Li 37*67e74705SXin Li std::array <unsigned, llvm::IPVK_Last + 1> NumValueSites; 38*67e74705SXin Li unsigned NumRegionCounters; 39*67e74705SXin Li uint64_t FunctionHash; 40*67e74705SXin Li std::unique_ptr<llvm::DenseMap<const Stmt *, unsigned>> RegionCounterMap; 41*67e74705SXin Li std::unique_ptr<llvm::DenseMap<const Stmt *, uint64_t>> StmtCountMap; 42*67e74705SXin Li std::unique_ptr<llvm::InstrProfRecord> ProfRecord; 43*67e74705SXin Li std::vector<uint64_t> RegionCounts; 44*67e74705SXin Li uint64_t CurrentRegionCount; 45*67e74705SXin Li /// \brief A flag that is set to true when this function doesn't need 46*67e74705SXin Li /// to have coverage mapping data. 47*67e74705SXin Li bool SkipCoverageMapping; 48*67e74705SXin Li 49*67e74705SXin Li public: CodeGenPGO(CodeGenModule & CGM)50*67e74705SXin Li CodeGenPGO(CodeGenModule &CGM) 51*67e74705SXin Li : CGM(CGM), NumValueSites({{0}}), NumRegionCounters(0), 52*67e74705SXin Li FunctionHash(0), CurrentRegionCount(0), SkipCoverageMapping(false) {} 53*67e74705SXin Li 54*67e74705SXin Li /// Whether or not we have PGO region data for the current function. This is 55*67e74705SXin Li /// false both when we have no data at all and when our data has been 56*67e74705SXin Li /// discarded. haveRegionCounts()57*67e74705SXin Li bool haveRegionCounts() const { return !RegionCounts.empty(); } 58*67e74705SXin Li 59*67e74705SXin Li /// Return the counter value of the current region. getCurrentRegionCount()60*67e74705SXin Li uint64_t getCurrentRegionCount() const { return CurrentRegionCount; } 61*67e74705SXin Li 62*67e74705SXin Li /// Set the counter value for the current region. This is used to keep track 63*67e74705SXin Li /// of changes to the most recent counter from control flow and non-local 64*67e74705SXin Li /// exits. setCurrentRegionCount(uint64_t Count)65*67e74705SXin Li void setCurrentRegionCount(uint64_t Count) { CurrentRegionCount = Count; } 66*67e74705SXin Li 67*67e74705SXin Li /// Check if an execution count is known for a given statement. If so, return 68*67e74705SXin Li /// true and put the value in Count; else return false. getStmtCount(const Stmt * S)69*67e74705SXin Li Optional<uint64_t> getStmtCount(const Stmt *S) { 70*67e74705SXin Li if (!StmtCountMap) 71*67e74705SXin Li return None; 72*67e74705SXin Li auto I = StmtCountMap->find(S); 73*67e74705SXin Li if (I == StmtCountMap->end()) 74*67e74705SXin Li return None; 75*67e74705SXin Li return I->second; 76*67e74705SXin Li } 77*67e74705SXin Li 78*67e74705SXin Li /// If the execution count for the current statement is known, record that 79*67e74705SXin Li /// as the current count. setCurrentStmt(const Stmt * S)80*67e74705SXin Li void setCurrentStmt(const Stmt *S) { 81*67e74705SXin Li if (auto Count = getStmtCount(S)) 82*67e74705SXin Li setCurrentRegionCount(*Count); 83*67e74705SXin Li } 84*67e74705SXin Li 85*67e74705SXin Li /// Assign counters to regions and configure them for PGO of a given 86*67e74705SXin Li /// function. Does nothing if instrumentation is not enabled and either 87*67e74705SXin Li /// generates global variables or associates PGO data with each of the 88*67e74705SXin Li /// counters depending on whether we are generating or using instrumentation. 89*67e74705SXin Li void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn); 90*67e74705SXin Li /// Emit a coverage mapping range with a counter zero 91*67e74705SXin Li /// for an unused declaration. 92*67e74705SXin Li void emitEmptyCounterMapping(const Decl *D, StringRef FuncName, 93*67e74705SXin Li llvm::GlobalValue::LinkageTypes Linkage); 94*67e74705SXin Li // Insert instrumentation or attach profile metadata at value sites 95*67e74705SXin Li void valueProfile(CGBuilderTy &Builder, uint32_t ValueKind, 96*67e74705SXin Li llvm::Instruction *ValueSite, llvm::Value *ValuePtr); 97*67e74705SXin Li private: 98*67e74705SXin Li void setFuncName(llvm::Function *Fn); 99*67e74705SXin Li void setFuncName(StringRef Name, llvm::GlobalValue::LinkageTypes Linkage); 100*67e74705SXin Li void mapRegionCounters(const Decl *D); 101*67e74705SXin Li void computeRegionCounts(const Decl *D); 102*67e74705SXin Li void applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader, 103*67e74705SXin Li llvm::Function *Fn); 104*67e74705SXin Li void loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader, 105*67e74705SXin Li bool IsInMainFile); 106*67e74705SXin Li bool skipRegionMappingForDecl(const Decl *D); 107*67e74705SXin Li void emitCounterRegionMapping(const Decl *D); 108*67e74705SXin Li 109*67e74705SXin Li public: 110*67e74705SXin Li void emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S); 111*67e74705SXin Li 112*67e74705SXin Li /// Return the region count for the counter at the given index. getRegionCount(const Stmt * S)113*67e74705SXin Li uint64_t getRegionCount(const Stmt *S) { 114*67e74705SXin Li if (!RegionCounterMap) 115*67e74705SXin Li return 0; 116*67e74705SXin Li if (!haveRegionCounts()) 117*67e74705SXin Li return 0; 118*67e74705SXin Li return RegionCounts[(*RegionCounterMap)[S]]; 119*67e74705SXin Li } 120*67e74705SXin Li }; 121*67e74705SXin Li 122*67e74705SXin Li } // end namespace CodeGen 123*67e74705SXin Li } // end namespace clang 124*67e74705SXin Li 125*67e74705SXin Li #endif 126