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