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 std::vector<uint64_t> *RegionCounts; 64 uint64_t CurrentRegionCount; 65 66 public: 67 CodeGenPGO(CodeGenModule &CGM) 68 : CGM(CGM), NumRegionCounters(0), RegionCounters(0), RegionCounterMap(0), 69 RegionCounts(0), CurrentRegionCount(0) {} 70 ~CodeGenPGO() {} 71 72 /// Whether or not we have PGO region data for the current function. This is 73 /// false both when we have no data at all and when our data has been 74 /// discarded. 75 bool haveRegionCounts() const { return RegionCounts != 0; } 76 77 /// Return the counter value of the current region. 78 uint64_t getCurrentRegionCount() const { return CurrentRegionCount; } 79 /// Return the counter value of the current region, or \p Min if it is larger. 80 uint64_t getCurrentRegionCountWithMin(uint64_t Min) { 81 return std::max(Min, CurrentRegionCount); 82 } 83 /// Set the counter value for the current region. This is used to keep track 84 /// of changes to the most recent counter from control flow and non-local 85 /// exits. 86 void setCurrentRegionCount(uint64_t Count) { CurrentRegionCount = Count; } 87 /// Indicate that the current region is never reached, and thus should have a 88 /// counter value of zero. This is important so that subsequent regions can 89 /// correctly track their parent counts. 90 void setCurrentRegionUnreachable() { setCurrentRegionCount(0); } 91 92 /// Calculate branch weights appropriate for PGO data 93 llvm::MDNode *createBranchWeights(uint64_t TrueCount, uint64_t FalseCount); 94 llvm::MDNode *createBranchWeights(ArrayRef<uint64_t> Weights); 95 96 /// Assign counters to regions and configure them for PGO of a given 97 /// function. Does nothing if instrumentation is not enabled and either 98 /// generates global variables or associates PGO data with each of the 99 /// counters depending on whether we are generating or using instrumentation. 100 void assignRegionCounters(GlobalDecl &GD); 101 /// Emit code to write counts for a given function to disk, if necessary. 102 void emitWriteoutFunction(GlobalDecl &GD); 103 /// Clean up region counter state. Must be called if assignRegionCounters is 104 /// used. 105 void destroyRegionCounters(); 106 /// Emit the logic to register region counter write out functions. Returns a 107 /// function that implements this logic. 108 static llvm::Function *emitInitialization(CodeGenModule &CGM); 109 110 private: 111 void mapRegionCounters(const Decl *D); 112 void loadRegionCounts(GlobalDecl &GD, PGOProfileData *PGOData); 113 void emitCounterVariables(); 114 115 /// Emit code to increment the counter at the given index 116 void emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter); 117 118 /// Return the region counter for the given statement. This should only be 119 /// called on statements that have a dedicated counter. 120 unsigned getRegionCounter(const Stmt *S) { 121 if (RegionCounterMap == 0) 122 return 0; 123 return (*RegionCounterMap)[S]; 124 } 125 126 /// Return the region count for the counter at the given index. 127 uint64_t getRegionCount(unsigned Counter) { 128 if (!haveRegionCounts()) 129 return 0; 130 return (*RegionCounts)[Counter]; 131 } 132 133 friend class RegionCounter; 134 }; 135 136 /// A counter for a particular region. This is the primary interface through 137 /// which clients manage PGO counters and their values. 138 class RegionCounter { 139 CodeGenPGO *PGO; 140 unsigned Counter; 141 uint64_t Count; 142 uint64_t ParentCount; 143 uint64_t RegionCount; 144 int64_t Adjust; 145 146 RegionCounter(CodeGenPGO &PGO, unsigned CounterIndex) 147 : PGO(&PGO), Counter(CounterIndex), Count(PGO.getRegionCount(Counter)), 148 ParentCount(PGO.getCurrentRegionCount()), Adjust(0) {} 149 150 public: 151 RegionCounter(CodeGenPGO &PGO, const Stmt *S) 152 : PGO(&PGO), Counter(PGO.getRegionCounter(S)), 153 Count(PGO.getRegionCount(Counter)), 154 ParentCount(PGO.getCurrentRegionCount()), Adjust(0) {} 155 156 /// Get the value of the counter. In most cases this is the number of times 157 /// the region of the counter was entered, but for switch labels it's the 158 /// number of direct jumps to that label. 159 uint64_t getCount() const { return Count; } 160 /// Get the value of the counter with adjustments applied. Adjustments occur 161 /// when control enters or leaves the region abnormally, ie, if there is a 162 /// jump to a label within the region, or if the function can return from 163 /// within the region. The adjusted count, then, is the value of the counter 164 /// at the end of the region. 165 uint64_t getAdjustedCount() const { 166 assert((Adjust > 0 || (uint64_t)(-Adjust) <= Count) && "Negative count"); 167 return Count + Adjust; 168 } 169 /// Get the value of the counter in this region's parent, ie, the region that 170 /// was active when this region began. This is useful for deriving counts in 171 /// implicitly counted regions, like the false case of a condition or the 172 /// normal exits of a loop. 173 uint64_t getParentCount() const { return ParentCount; } 174 175 /// Get the number of times the condition of a loop will evaluate false. This 176 /// is the number of times we enter the loop, adjusted by the difference 177 /// between entering and exiting the loop body normally, excepting that 178 /// 'continue' statements also bring us back here. 179 /// 180 /// Undefined if this counter is not counting a loop. 181 uint64_t getLoopExitCount() const { 182 return getParentCount() + getContinueCounter().getCount() + 183 getAdjustedCount() - getCount(); 184 } 185 /// Get the associated break counter. Undefined if this counter is not 186 /// counting a loop. 187 RegionCounter getBreakCounter() const { 188 return RegionCounter(*PGO, Counter + 1); 189 } 190 /// Get the associated continue counter. Undefined if this counter is not 191 /// counting a loop. 192 RegionCounter getContinueCounter() const { 193 return RegionCounter(*PGO, Counter + 2); 194 } 195 196 /// Activate the counter by emitting an increment and starting to track 197 /// adjustments. If AddIncomingFallThrough is true, the current region count 198 /// will be added to the counter for the purposes of tracking the region. 199 void beginRegion(CGBuilderTy &Builder, bool AddIncomingFallThrough=false) { 200 RegionCount = Count; 201 if (AddIncomingFallThrough) 202 RegionCount += PGO->getCurrentRegionCount(); 203 PGO->setCurrentRegionCount(RegionCount); 204 PGO->emitCounterIncrement(Builder, Counter); 205 } 206 /// For counters on boolean branches, begins tracking adjustments for the 207 /// uncounted path. 208 void beginElseRegion() { 209 RegionCount = ParentCount - Count; 210 PGO->setCurrentRegionCount(RegionCount); 211 } 212 213 /// Adjust for non-local control flow after emitting a subexpression or 214 /// substatement. This must be called to account for constructs such as gotos, 215 /// labels, and returns, so that we can ensure that our region's count is 216 /// correct in the code that follows. 217 void adjustForControlFlow() { 218 Adjust += PGO->getCurrentRegionCount() - RegionCount; 219 } 220 /// Commit all adjustments to the current region. This should be called after 221 /// all blocks that adjust for control flow count have been emitted. 222 void applyAdjustmentsToRegion() { 223 PGO->setCurrentRegionCount(ParentCount + Adjust); 224 } 225 }; 226 227 } // end namespace CodeGen 228 } // end namespace clang 229 230 #endif 231