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