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