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 CLANG_CODEGEN_CODEGENPGO_H 15 #define CLANG_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/OwningPtr.h" 22 #include "llvm/ADT/StringMap.h" 23 #include "llvm/Support/MemoryBuffer.h" 24 25 namespace clang { 26 namespace CodeGen { 27 class RegionCounter; 28 29 /// The raw counter data from an instrumented PGO binary 30 class PGOProfileData { 31 private: 32 /// The PGO data 33 llvm::OwningPtr<llvm::MemoryBuffer> DataBuffer; 34 /// Offsets into DataBuffer for each function's counters 35 llvm::StringMap<unsigned> DataOffsets; 36 /// Execution counts for each function. 37 llvm::StringMap<uint64_t> FunctionCounts; 38 /// The maximal execution count among all functions. 39 uint64_t MaxFunctionCount; 40 CodeGenModule &CGM; 41 public: 42 PGOProfileData(CodeGenModule &CGM, std::string Path); 43 /// Fill Counts with the profile data for the given function name. Returns 44 /// false on success. 45 bool getFunctionCounts(StringRef MangledName, std::vector<uint64_t> &Counts); 46 /// Return true if a function is hot. If we know nothing about the function, 47 /// return false. 48 bool isHotFunction(StringRef MangledName); 49 /// Return true if a function is cold. If we know nothing about the function, 50 /// return false. 51 bool isColdFunction(StringRef MangledName); 52 }; 53 54 /// Per-function PGO state. This class should generally not be used directly, 55 /// but instead through the CodeGenFunction and RegionCounter types. 56 class CodeGenPGO { 57 private: 58 CodeGenModule &CGM; 59 60 unsigned NumRegionCounters; 61 llvm::GlobalVariable *RegionCounters; 62 llvm::DenseMap<const Stmt*, unsigned> *RegionCounterMap; 63 llvm::DenseMap<const Stmt*, uint64_t> *StmtCountMap; 64 std::vector<uint64_t> *RegionCounts; 65 uint64_t CurrentRegionCount; 66 67 public: 68 CodeGenPGO(CodeGenModule &CGM) 69 : CGM(CGM), NumRegionCounters(0), RegionCounters(0), RegionCounterMap(0), 70 StmtCountMap(0), RegionCounts(0), CurrentRegionCount(0) {} 71 ~CodeGenPGO() {} 72 73 /// Whether or not we have PGO region data for the current function. This is 74 /// false both when we have no data at all and when our data has been 75 /// discarded. 76 bool haveRegionCounts() const { return RegionCounts != 0; } 77 78 /// Return the counter value of the current region. 79 uint64_t getCurrentRegionCount() const { return CurrentRegionCount; } 80 81 /// Set the counter value for the current region. This is used to keep track 82 /// of changes to the most recent counter from control flow and non-local 83 /// exits. 84 void setCurrentRegionCount(uint64_t Count) { CurrentRegionCount = Count; } 85 86 /// Indicate that the current region is never reached, and thus should have a 87 /// counter value of zero. This is important so that subsequent regions can 88 /// correctly track their parent counts. 89 void setCurrentRegionUnreachable() { setCurrentRegionCount(0); } 90 91 /// Check if an execution count is known for a given statement. If so, return 92 /// true and put the value in Count; else return false. 93 bool getStmtCount(const Stmt *S, uint64_t &Count) { 94 if (!StmtCountMap) 95 return false; 96 llvm::DenseMap<const Stmt*, uint64_t>::const_iterator 97 I = StmtCountMap->find(S); 98 if (I == StmtCountMap->end()) 99 return false; 100 Count = I->second; 101 return true; 102 } 103 104 /// If the execution count for the current statement is known, record that 105 /// as the current count. 106 void setCurrentStmt(const Stmt *S) { 107 uint64_t Count; 108 if (getStmtCount(S, Count)) 109 setCurrentRegionCount(Count); 110 } 111 112 /// Calculate branch weights appropriate for PGO data 113 llvm::MDNode *createBranchWeights(uint64_t TrueCount, uint64_t FalseCount); 114 llvm::MDNode *createBranchWeights(ArrayRef<uint64_t> Weights); 115 llvm::MDNode *createLoopWeights(const Stmt *Cond, RegionCounter &Cnt); 116 117 /// Assign counters to regions and configure them for PGO of a given 118 /// function. Does nothing if instrumentation is not enabled and either 119 /// generates global variables or associates PGO data with each of the 120 /// counters depending on whether we are generating or using instrumentation. 121 void assignRegionCounters(GlobalDecl &GD); 122 /// Emit code to write counts for a given function to disk, if necessary. 123 void emitWriteoutFunction(GlobalDecl &GD); 124 /// Clean up region counter state. Must be called if assignRegionCounters is 125 /// used. 126 void destroyRegionCounters(); 127 /// Emit the logic to register region counter write out functions. Returns a 128 /// function that implements this logic. 129 static llvm::Function *emitInitialization(CodeGenModule &CGM); 130 131 private: 132 void mapRegionCounters(const Decl *D); 133 void computeRegionCounts(const Decl *D); 134 void loadRegionCounts(GlobalDecl &GD, PGOProfileData *PGOData); 135 void emitCounterVariables(); 136 137 /// Emit code to increment the counter at the given index 138 void emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter); 139 140 /// Return the region counter for the given statement. This should only be 141 /// called on statements that have a dedicated counter. 142 unsigned getRegionCounter(const Stmt *S) { 143 if (RegionCounterMap == 0) 144 return 0; 145 return (*RegionCounterMap)[S]; 146 } 147 148 /// Return the region count for the counter at the given index. 149 uint64_t getRegionCount(unsigned Counter) { 150 if (!haveRegionCounts()) 151 return 0; 152 return (*RegionCounts)[Counter]; 153 } 154 155 friend class RegionCounter; 156 }; 157 158 /// A counter for a particular region. This is the primary interface through 159 /// which clients manage PGO counters and their values. 160 class RegionCounter { 161 CodeGenPGO *PGO; 162 unsigned Counter; 163 uint64_t Count; 164 uint64_t ParentCount; 165 uint64_t RegionCount; 166 int64_t Adjust; 167 168 RegionCounter(CodeGenPGO &PGO, unsigned CounterIndex) 169 : PGO(&PGO), Counter(CounterIndex), Count(PGO.getRegionCount(Counter)), 170 ParentCount(PGO.getCurrentRegionCount()), Adjust(0) {} 171 172 public: 173 RegionCounter(CodeGenPGO &PGO, const Stmt *S) 174 : PGO(&PGO), Counter(PGO.getRegionCounter(S)), 175 Count(PGO.getRegionCount(Counter)), 176 ParentCount(PGO.getCurrentRegionCount()), Adjust(0) {} 177 178 /// Get the value of the counter. In most cases this is the number of times 179 /// the region of the counter was entered, but for switch labels it's the 180 /// number of direct jumps to that label. 181 uint64_t getCount() const { return Count; } 182 183 /// Get the value of the counter with adjustments applied. Adjustments occur 184 /// when control enters or leaves the region abnormally; i.e., if there is a 185 /// jump to a label within the region, or if the function can return from 186 /// within the region. The adjusted count, then, is the value of the counter 187 /// at the end of the region. 188 uint64_t getAdjustedCount() const { 189 return Count + Adjust; 190 } 191 192 /// Get the value of the counter in this region's parent, i.e., the region 193 /// that was active when this region began. This is useful for deriving 194 /// counts in implicitly counted regions, like the false case of a condition 195 /// or the normal exits of a loop. 196 uint64_t getParentCount() const { return ParentCount; } 197 198 /// Activate the counter by emitting an increment and starting to track 199 /// adjustments. If AddIncomingFallThrough is true, the current region count 200 /// will be added to the counter for the purposes of tracking the region. 201 void beginRegion(CGBuilderTy &Builder, bool AddIncomingFallThrough=false) { 202 beginRegion(AddIncomingFallThrough); 203 PGO->emitCounterIncrement(Builder, Counter); 204 } 205 void beginRegion(bool AddIncomingFallThrough=false) { 206 RegionCount = Count; 207 if (AddIncomingFallThrough) 208 RegionCount += PGO->getCurrentRegionCount(); 209 PGO->setCurrentRegionCount(RegionCount); 210 } 211 212 /// For counters on boolean branches, begins tracking adjustments for the 213 /// uncounted path. 214 void beginElseRegion() { 215 RegionCount = ParentCount - Count; 216 PGO->setCurrentRegionCount(RegionCount); 217 } 218 219 /// Reset the current region count. 220 void setCurrentRegionCount(uint64_t CurrentCount) { 221 RegionCount = CurrentCount; 222 PGO->setCurrentRegionCount(RegionCount); 223 } 224 225 /// Adjust for non-local control flow after emitting a subexpression or 226 /// substatement. This must be called to account for constructs such as gotos, 227 /// labels, and returns, so that we can ensure that our region's count is 228 /// correct in the code that follows. 229 void adjustForControlFlow() { 230 Adjust += PGO->getCurrentRegionCount() - RegionCount; 231 // Reset the region count in case this is called again later. 232 RegionCount = PGO->getCurrentRegionCount(); 233 } 234 235 /// Commit all adjustments to the current region. If the region is a loop, 236 /// the LoopAdjust value should be the count of all the breaks and continues 237 /// from the loop, to compensate for those counts being deducted from the 238 /// adjustments for the body of the loop. 239 void applyAdjustmentsToRegion(uint64_t LoopAdjust) { 240 PGO->setCurrentRegionCount(ParentCount + Adjust + LoopAdjust); 241 } 242 }; 243 244 } // end namespace CodeGen 245 } // end namespace clang 246 247 #endif 248