1*0a6a1f1dSLionel Sambuc //===--- CodeGenPGO.h - PGO Instrumentation for LLVM CodeGen ----*- C++ -*-===// 2*0a6a1f1dSLionel Sambuc // 3*0a6a1f1dSLionel Sambuc // The LLVM Compiler Infrastructure 4*0a6a1f1dSLionel Sambuc // 5*0a6a1f1dSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*0a6a1f1dSLionel Sambuc // License. See LICENSE.TXT for details. 7*0a6a1f1dSLionel Sambuc // 8*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===// 9*0a6a1f1dSLionel Sambuc // 10*0a6a1f1dSLionel Sambuc // Instrumentation-based profile-guided optimization 11*0a6a1f1dSLionel Sambuc // 12*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===// 13*0a6a1f1dSLionel Sambuc 14*0a6a1f1dSLionel Sambuc #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENPGO_H 15*0a6a1f1dSLionel Sambuc #define LLVM_CLANG_LIB_CODEGEN_CODEGENPGO_H 16*0a6a1f1dSLionel Sambuc 17*0a6a1f1dSLionel Sambuc #include "CGBuilder.h" 18*0a6a1f1dSLionel Sambuc #include "CodeGenModule.h" 19*0a6a1f1dSLionel Sambuc #include "CodeGenTypes.h" 20*0a6a1f1dSLionel Sambuc #include "clang/Frontend/CodeGenOptions.h" 21*0a6a1f1dSLionel Sambuc #include "llvm/ADT/StringMap.h" 22*0a6a1f1dSLionel Sambuc #include "llvm/Support/MemoryBuffer.h" 23*0a6a1f1dSLionel Sambuc #include <memory> 24*0a6a1f1dSLionel Sambuc 25*0a6a1f1dSLionel Sambuc namespace clang { 26*0a6a1f1dSLionel Sambuc namespace CodeGen { 27*0a6a1f1dSLionel Sambuc class RegionCounter; 28*0a6a1f1dSLionel Sambuc 29*0a6a1f1dSLionel Sambuc /// Per-function PGO state. This class should generally not be used directly, 30*0a6a1f1dSLionel Sambuc /// but instead through the CodeGenFunction and RegionCounter types. 31*0a6a1f1dSLionel Sambuc class CodeGenPGO { 32*0a6a1f1dSLionel Sambuc private: 33*0a6a1f1dSLionel Sambuc CodeGenModule &CGM; 34*0a6a1f1dSLionel Sambuc std::string FuncName; 35*0a6a1f1dSLionel Sambuc llvm::GlobalVariable *FuncNameVar; 36*0a6a1f1dSLionel Sambuc 37*0a6a1f1dSLionel Sambuc unsigned NumRegionCounters; 38*0a6a1f1dSLionel Sambuc uint64_t FunctionHash; 39*0a6a1f1dSLionel Sambuc std::unique_ptr<llvm::DenseMap<const Stmt *, unsigned>> RegionCounterMap; 40*0a6a1f1dSLionel Sambuc std::unique_ptr<llvm::DenseMap<const Stmt *, uint64_t>> StmtCountMap; 41*0a6a1f1dSLionel Sambuc std::vector<uint64_t> RegionCounts; 42*0a6a1f1dSLionel Sambuc uint64_t CurrentRegionCount; 43*0a6a1f1dSLionel Sambuc /// \brief A flag that is set to true when this function doesn't need 44*0a6a1f1dSLionel Sambuc /// to have coverage mapping data. 45*0a6a1f1dSLionel Sambuc bool SkipCoverageMapping; 46*0a6a1f1dSLionel Sambuc 47*0a6a1f1dSLionel Sambuc public: CodeGenPGO(CodeGenModule & CGM)48*0a6a1f1dSLionel Sambuc CodeGenPGO(CodeGenModule &CGM) 49*0a6a1f1dSLionel Sambuc : CGM(CGM), NumRegionCounters(0), FunctionHash(0), CurrentRegionCount(0), 50*0a6a1f1dSLionel Sambuc SkipCoverageMapping(false) {} 51*0a6a1f1dSLionel Sambuc 52*0a6a1f1dSLionel Sambuc /// Whether or not we have PGO region data for the current function. This is 53*0a6a1f1dSLionel Sambuc /// false both when we have no data at all and when our data has been 54*0a6a1f1dSLionel Sambuc /// discarded. haveRegionCounts()55*0a6a1f1dSLionel Sambuc bool haveRegionCounts() const { return !RegionCounts.empty(); } 56*0a6a1f1dSLionel Sambuc 57*0a6a1f1dSLionel Sambuc /// Return the counter value of the current region. getCurrentRegionCount()58*0a6a1f1dSLionel Sambuc uint64_t getCurrentRegionCount() const { return CurrentRegionCount; } 59*0a6a1f1dSLionel Sambuc 60*0a6a1f1dSLionel Sambuc /// Set the counter value for the current region. This is used to keep track 61*0a6a1f1dSLionel Sambuc /// of changes to the most recent counter from control flow and non-local 62*0a6a1f1dSLionel Sambuc /// exits. setCurrentRegionCount(uint64_t Count)63*0a6a1f1dSLionel Sambuc void setCurrentRegionCount(uint64_t Count) { CurrentRegionCount = Count; } 64*0a6a1f1dSLionel Sambuc 65*0a6a1f1dSLionel Sambuc /// Indicate that the current region is never reached, and thus should have a 66*0a6a1f1dSLionel Sambuc /// counter value of zero. This is important so that subsequent regions can 67*0a6a1f1dSLionel Sambuc /// correctly track their parent counts. setCurrentRegionUnreachable()68*0a6a1f1dSLionel Sambuc void setCurrentRegionUnreachable() { setCurrentRegionCount(0); } 69*0a6a1f1dSLionel Sambuc 70*0a6a1f1dSLionel Sambuc /// Check if an execution count is known for a given statement. If so, return 71*0a6a1f1dSLionel Sambuc /// true and put the value in Count; else return false. getStmtCount(const Stmt * S,uint64_t & Count)72*0a6a1f1dSLionel Sambuc bool getStmtCount(const Stmt *S, uint64_t &Count) { 73*0a6a1f1dSLionel Sambuc if (!StmtCountMap) 74*0a6a1f1dSLionel Sambuc return false; 75*0a6a1f1dSLionel Sambuc llvm::DenseMap<const Stmt*, uint64_t>::const_iterator 76*0a6a1f1dSLionel Sambuc I = StmtCountMap->find(S); 77*0a6a1f1dSLionel Sambuc if (I == StmtCountMap->end()) 78*0a6a1f1dSLionel Sambuc return false; 79*0a6a1f1dSLionel Sambuc Count = I->second; 80*0a6a1f1dSLionel Sambuc return true; 81*0a6a1f1dSLionel Sambuc } 82*0a6a1f1dSLionel Sambuc 83*0a6a1f1dSLionel Sambuc /// If the execution count for the current statement is known, record that 84*0a6a1f1dSLionel Sambuc /// as the current count. setCurrentStmt(const Stmt * S)85*0a6a1f1dSLionel Sambuc void setCurrentStmt(const Stmt *S) { 86*0a6a1f1dSLionel Sambuc uint64_t Count; 87*0a6a1f1dSLionel Sambuc if (getStmtCount(S, Count)) 88*0a6a1f1dSLionel Sambuc setCurrentRegionCount(Count); 89*0a6a1f1dSLionel Sambuc } 90*0a6a1f1dSLionel Sambuc 91*0a6a1f1dSLionel Sambuc /// Calculate branch weights appropriate for PGO data 92*0a6a1f1dSLionel Sambuc llvm::MDNode *createBranchWeights(uint64_t TrueCount, uint64_t FalseCount); 93*0a6a1f1dSLionel Sambuc llvm::MDNode *createBranchWeights(ArrayRef<uint64_t> Weights); 94*0a6a1f1dSLionel Sambuc llvm::MDNode *createLoopWeights(const Stmt *Cond, RegionCounter &Cnt); 95*0a6a1f1dSLionel Sambuc 96*0a6a1f1dSLionel Sambuc /// Check if we need to emit coverage mapping for a given declaration 97*0a6a1f1dSLionel Sambuc void checkGlobalDecl(GlobalDecl GD); 98*0a6a1f1dSLionel Sambuc /// Assign counters to regions and configure them for PGO of a given 99*0a6a1f1dSLionel Sambuc /// function. Does nothing if instrumentation is not enabled and either 100*0a6a1f1dSLionel Sambuc /// generates global variables or associates PGO data with each of the 101*0a6a1f1dSLionel Sambuc /// counters depending on whether we are generating or using instrumentation. 102*0a6a1f1dSLionel Sambuc void assignRegionCounters(const Decl *D, llvm::Function *Fn); 103*0a6a1f1dSLionel Sambuc /// Emit a coverage mapping range with a counter zero 104*0a6a1f1dSLionel Sambuc /// for an unused declaration. 105*0a6a1f1dSLionel Sambuc void emitEmptyCounterMapping(const Decl *D, StringRef FuncName, 106*0a6a1f1dSLionel Sambuc llvm::GlobalValue::LinkageTypes Linkage); 107*0a6a1f1dSLionel Sambuc private: 108*0a6a1f1dSLionel Sambuc void setFuncName(llvm::Function *Fn); 109*0a6a1f1dSLionel Sambuc void setFuncName(StringRef Name, llvm::GlobalValue::LinkageTypes Linkage); 110*0a6a1f1dSLionel Sambuc void createFuncNameVar(llvm::GlobalValue::LinkageTypes Linkage); 111*0a6a1f1dSLionel Sambuc void mapRegionCounters(const Decl *D); 112*0a6a1f1dSLionel Sambuc void computeRegionCounts(const Decl *D); 113*0a6a1f1dSLionel Sambuc void applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader, 114*0a6a1f1dSLionel Sambuc llvm::Function *Fn); 115*0a6a1f1dSLionel Sambuc void loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader, 116*0a6a1f1dSLionel Sambuc bool IsInMainFile); 117*0a6a1f1dSLionel Sambuc void emitCounterVariables(); 118*0a6a1f1dSLionel Sambuc void emitCounterRegionMapping(const Decl *D); 119*0a6a1f1dSLionel Sambuc 120*0a6a1f1dSLionel Sambuc /// Emit code to increment the counter at the given index 121*0a6a1f1dSLionel Sambuc void emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter); 122*0a6a1f1dSLionel Sambuc 123*0a6a1f1dSLionel Sambuc /// Return the region counter for the given statement. This should only be 124*0a6a1f1dSLionel Sambuc /// called on statements that have a dedicated counter. getRegionCounter(const Stmt * S)125*0a6a1f1dSLionel Sambuc unsigned getRegionCounter(const Stmt *S) { 126*0a6a1f1dSLionel Sambuc if (!RegionCounterMap) 127*0a6a1f1dSLionel Sambuc return 0; 128*0a6a1f1dSLionel Sambuc return (*RegionCounterMap)[S]; 129*0a6a1f1dSLionel Sambuc } 130*0a6a1f1dSLionel Sambuc 131*0a6a1f1dSLionel Sambuc /// Return the region count for the counter at the given index. getRegionCount(unsigned Counter)132*0a6a1f1dSLionel Sambuc uint64_t getRegionCount(unsigned Counter) { 133*0a6a1f1dSLionel Sambuc if (!haveRegionCounts()) 134*0a6a1f1dSLionel Sambuc return 0; 135*0a6a1f1dSLionel Sambuc return RegionCounts[Counter]; 136*0a6a1f1dSLionel Sambuc } 137*0a6a1f1dSLionel Sambuc 138*0a6a1f1dSLionel Sambuc friend class RegionCounter; 139*0a6a1f1dSLionel Sambuc }; 140*0a6a1f1dSLionel Sambuc 141*0a6a1f1dSLionel Sambuc /// A counter for a particular region. This is the primary interface through 142*0a6a1f1dSLionel Sambuc /// which clients manage PGO counters and their values. 143*0a6a1f1dSLionel Sambuc class RegionCounter { 144*0a6a1f1dSLionel Sambuc CodeGenPGO *PGO; 145*0a6a1f1dSLionel Sambuc unsigned Counter; 146*0a6a1f1dSLionel Sambuc uint64_t Count; 147*0a6a1f1dSLionel Sambuc uint64_t ParentCount; 148*0a6a1f1dSLionel Sambuc uint64_t RegionCount; 149*0a6a1f1dSLionel Sambuc int64_t Adjust; 150*0a6a1f1dSLionel Sambuc RegionCounter(CodeGenPGO & PGO,unsigned CounterIndex)151*0a6a1f1dSLionel Sambuc RegionCounter(CodeGenPGO &PGO, unsigned CounterIndex) 152*0a6a1f1dSLionel Sambuc : PGO(&PGO), Counter(CounterIndex), Count(PGO.getRegionCount(Counter)), 153*0a6a1f1dSLionel Sambuc ParentCount(PGO.getCurrentRegionCount()), Adjust(0) {} 154*0a6a1f1dSLionel Sambuc 155*0a6a1f1dSLionel Sambuc public: RegionCounter(CodeGenPGO & PGO,const Stmt * S)156*0a6a1f1dSLionel Sambuc RegionCounter(CodeGenPGO &PGO, const Stmt *S) 157*0a6a1f1dSLionel Sambuc : PGO(&PGO), Counter(PGO.getRegionCounter(S)), 158*0a6a1f1dSLionel Sambuc Count(PGO.getRegionCount(Counter)), 159*0a6a1f1dSLionel Sambuc ParentCount(PGO.getCurrentRegionCount()), Adjust(0) {} 160*0a6a1f1dSLionel Sambuc 161*0a6a1f1dSLionel Sambuc /// Get the value of the counter. In most cases this is the number of times 162*0a6a1f1dSLionel Sambuc /// the region of the counter was entered, but for switch labels it's the 163*0a6a1f1dSLionel Sambuc /// number of direct jumps to that label. getCount()164*0a6a1f1dSLionel Sambuc uint64_t getCount() const { return Count; } 165*0a6a1f1dSLionel Sambuc 166*0a6a1f1dSLionel Sambuc /// Get the value of the counter with adjustments applied. Adjustments occur 167*0a6a1f1dSLionel Sambuc /// when control enters or leaves the region abnormally; i.e., if there is a 168*0a6a1f1dSLionel Sambuc /// jump to a label within the region, or if the function can return from 169*0a6a1f1dSLionel Sambuc /// within the region. The adjusted count, then, is the value of the counter 170*0a6a1f1dSLionel Sambuc /// at the end of the region. getAdjustedCount()171*0a6a1f1dSLionel Sambuc uint64_t getAdjustedCount() const { 172*0a6a1f1dSLionel Sambuc return Count + Adjust; 173*0a6a1f1dSLionel Sambuc } 174*0a6a1f1dSLionel Sambuc 175*0a6a1f1dSLionel Sambuc /// Get the value of the counter in this region's parent, i.e., the region 176*0a6a1f1dSLionel Sambuc /// that was active when this region began. This is useful for deriving 177*0a6a1f1dSLionel Sambuc /// counts in implicitly counted regions, like the false case of a condition 178*0a6a1f1dSLionel Sambuc /// or the normal exits of a loop. getParentCount()179*0a6a1f1dSLionel Sambuc uint64_t getParentCount() const { return ParentCount; } 180*0a6a1f1dSLionel Sambuc 181*0a6a1f1dSLionel Sambuc /// Activate the counter by emitting an increment and starting to track 182*0a6a1f1dSLionel Sambuc /// adjustments. If AddIncomingFallThrough is true, the current region count 183*0a6a1f1dSLionel Sambuc /// will be added to the counter for the purposes of tracking the region. 184*0a6a1f1dSLionel Sambuc void beginRegion(CGBuilderTy &Builder, bool AddIncomingFallThrough=false) { 185*0a6a1f1dSLionel Sambuc beginRegion(AddIncomingFallThrough); 186*0a6a1f1dSLionel Sambuc PGO->emitCounterIncrement(Builder, Counter); 187*0a6a1f1dSLionel Sambuc } 188*0a6a1f1dSLionel Sambuc void beginRegion(bool AddIncomingFallThrough=false) { 189*0a6a1f1dSLionel Sambuc RegionCount = Count; 190*0a6a1f1dSLionel Sambuc if (AddIncomingFallThrough) 191*0a6a1f1dSLionel Sambuc RegionCount += PGO->getCurrentRegionCount(); 192*0a6a1f1dSLionel Sambuc PGO->setCurrentRegionCount(RegionCount); 193*0a6a1f1dSLionel Sambuc } 194*0a6a1f1dSLionel Sambuc 195*0a6a1f1dSLionel Sambuc /// For counters on boolean branches, begins tracking adjustments for the 196*0a6a1f1dSLionel Sambuc /// uncounted path. beginElseRegion()197*0a6a1f1dSLionel Sambuc void beginElseRegion() { 198*0a6a1f1dSLionel Sambuc RegionCount = ParentCount - Count; 199*0a6a1f1dSLionel Sambuc PGO->setCurrentRegionCount(RegionCount); 200*0a6a1f1dSLionel Sambuc } 201*0a6a1f1dSLionel Sambuc 202*0a6a1f1dSLionel Sambuc /// Reset the current region count. setCurrentRegionCount(uint64_t CurrentCount)203*0a6a1f1dSLionel Sambuc void setCurrentRegionCount(uint64_t CurrentCount) { 204*0a6a1f1dSLionel Sambuc RegionCount = CurrentCount; 205*0a6a1f1dSLionel Sambuc PGO->setCurrentRegionCount(RegionCount); 206*0a6a1f1dSLionel Sambuc } 207*0a6a1f1dSLionel Sambuc 208*0a6a1f1dSLionel Sambuc /// Adjust for non-local control flow after emitting a subexpression or 209*0a6a1f1dSLionel Sambuc /// substatement. This must be called to account for constructs such as gotos, 210*0a6a1f1dSLionel Sambuc /// labels, and returns, so that we can ensure that our region's count is 211*0a6a1f1dSLionel Sambuc /// correct in the code that follows. adjustForControlFlow()212*0a6a1f1dSLionel Sambuc void adjustForControlFlow() { 213*0a6a1f1dSLionel Sambuc Adjust += PGO->getCurrentRegionCount() - RegionCount; 214*0a6a1f1dSLionel Sambuc // Reset the region count in case this is called again later. 215*0a6a1f1dSLionel Sambuc RegionCount = PGO->getCurrentRegionCount(); 216*0a6a1f1dSLionel Sambuc } 217*0a6a1f1dSLionel Sambuc 218*0a6a1f1dSLionel Sambuc /// Commit all adjustments to the current region. If the region is a loop, 219*0a6a1f1dSLionel Sambuc /// the LoopAdjust value should be the count of all the breaks and continues 220*0a6a1f1dSLionel Sambuc /// from the loop, to compensate for those counts being deducted from the 221*0a6a1f1dSLionel Sambuc /// adjustments for the body of the loop. applyAdjustmentsToRegion(uint64_t LoopAdjust)222*0a6a1f1dSLionel Sambuc void applyAdjustmentsToRegion(uint64_t LoopAdjust) { 223*0a6a1f1dSLionel Sambuc PGO->setCurrentRegionCount(ParentCount + Adjust + LoopAdjust); 224*0a6a1f1dSLionel Sambuc } 225*0a6a1f1dSLionel Sambuc }; 226*0a6a1f1dSLionel Sambuc 227*0a6a1f1dSLionel Sambuc } // end namespace CodeGen 228*0a6a1f1dSLionel Sambuc } // end namespace clang 229*0a6a1f1dSLionel Sambuc 230*0a6a1f1dSLionel Sambuc #endif 231