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