blob: e859324ae086048d7f9de55fef9c86281480fe86 [file] [log] [blame]
Justin Bogneref512b92014-01-06 22:27:43 +00001//===--- 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"
Justin Bogneref512b92014-01-06 22:27:43 +000021#include "llvm/ADT/StringMap.h"
22#include "llvm/Support/MemoryBuffer.h"
Ahmed Charlesdfca6f92014-03-09 11:36:40 +000023#include <memory>
Justin Bogneref512b92014-01-06 22:27:43 +000024
25namespace clang {
26namespace CodeGen {
27class RegionCounter;
28
Justin Bognerd66a17d2014-03-12 21:06:31 +000029/// The raw counter data from an instrumented PGO binary
30class PGOProfileData {
31private:
32 /// The PGO data
33 std::unique_ptr<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;
41public:
42 PGOProfileData(CodeGenModule &CGM, std::string Path);
43 /// Fill Counts with the profile data for the given function name. Returns
44 /// false on success.
Justin Bognerb4416f52014-03-18 21:58:06 +000045 bool getFunctionCounts(StringRef FuncName, uint64_t &FuncHash,
46 std::vector<uint64_t> &Counts);
Justin Bognerd66a17d2014-03-12 21:06:31 +000047 /// Return the maximum of all known function counts.
48 uint64_t getMaximumFunctionCount() { return MaxFunctionCount; }
49};
50
Justin Bogneref512b92014-01-06 22:27:43 +000051/// Per-function PGO state. This class should generally not be used directly,
52/// but instead through the CodeGenFunction and RegionCounter types.
53class CodeGenPGO {
54private:
55 CodeGenModule &CGM;
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000056 std::string *PrefixedFuncName;
57 StringRef RawFuncName;
58 llvm::GlobalValue::LinkageTypes FuncLinkage;
Justin Bogneref512b92014-01-06 22:27:43 +000059
60 unsigned NumRegionCounters;
Justin Bognerb4416f52014-03-18 21:58:06 +000061 uint64_t FunctionHash;
Justin Bogneref512b92014-01-06 22:27:43 +000062 llvm::GlobalVariable *RegionCounters;
63 llvm::DenseMap<const Stmt*, unsigned> *RegionCounterMap;
Bob Wilsonbf854f02014-02-17 19:21:09 +000064 llvm::DenseMap<const Stmt*, uint64_t> *StmtCountMap;
Justin Bogneref512b92014-01-06 22:27:43 +000065 std::vector<uint64_t> *RegionCounts;
66 uint64_t CurrentRegionCount;
67
68public:
69 CodeGenPGO(CodeGenModule &CGM)
Justin Bognerb4416f52014-03-18 21:58:06 +000070 : CGM(CGM), PrefixedFuncName(0), NumRegionCounters(0), FunctionHash(0),
71 RegionCounters(0), RegionCounterMap(0), StmtCountMap(0),
72 RegionCounts(0), CurrentRegionCount(0) {}
Bob Wilsonda1ebed2014-03-06 04:55:41 +000073 ~CodeGenPGO() {
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000074 if (PrefixedFuncName) delete PrefixedFuncName;
Bob Wilsonda1ebed2014-03-06 04:55:41 +000075 }
Justin Bogneref512b92014-01-06 22:27:43 +000076
77 /// Whether or not we have PGO region data for the current function. This is
78 /// false both when we have no data at all and when our data has been
79 /// discarded.
80 bool haveRegionCounts() const { return RegionCounts != 0; }
81
Bob Wilsonda1ebed2014-03-06 04:55:41 +000082 /// Get the string used to identify this function in the profile data.
83 /// For functions with local linkage, this includes the main file name.
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +000084 StringRef getFuncName() const { return StringRef(*PrefixedFuncName); }
85 std::string getFuncVarName(StringRef VarName) const {
86 return ("__llvm_pgo_" + VarName + "_" + RawFuncName).str();
87 }
Bob Wilsonda1ebed2014-03-06 04:55:41 +000088
Justin Bogneref512b92014-01-06 22:27:43 +000089 /// Return the counter value of the current region.
90 uint64_t getCurrentRegionCount() const { return CurrentRegionCount; }
Bob Wilsonbf854f02014-02-17 19:21:09 +000091
Justin Bogneref512b92014-01-06 22:27:43 +000092 /// Set the counter value for the current region. This is used to keep track
93 /// of changes to the most recent counter from control flow and non-local
94 /// exits.
95 void setCurrentRegionCount(uint64_t Count) { CurrentRegionCount = Count; }
Bob Wilsonbf854f02014-02-17 19:21:09 +000096
Justin Bogner06bd6d02014-01-13 21:24:18 +000097 /// Indicate that the current region is never reached, and thus should have a
98 /// counter value of zero. This is important so that subsequent regions can
99 /// correctly track their parent counts.
100 void setCurrentRegionUnreachable() { setCurrentRegionCount(0); }
Justin Bogneref512b92014-01-06 22:27:43 +0000101
Bob Wilsonbf854f02014-02-17 19:21:09 +0000102 /// Check if an execution count is known for a given statement. If so, return
103 /// true and put the value in Count; else return false.
104 bool getStmtCount(const Stmt *S, uint64_t &Count) {
105 if (!StmtCountMap)
106 return false;
107 llvm::DenseMap<const Stmt*, uint64_t>::const_iterator
108 I = StmtCountMap->find(S);
109 if (I == StmtCountMap->end())
110 return false;
111 Count = I->second;
112 return true;
113 }
114
115 /// If the execution count for the current statement is known, record that
116 /// as the current count.
117 void setCurrentStmt(const Stmt *S) {
118 uint64_t Count;
119 if (getStmtCount(S, Count))
120 setCurrentRegionCount(Count);
121 }
122
Justin Bogneref512b92014-01-06 22:27:43 +0000123 /// Calculate branch weights appropriate for PGO data
124 llvm::MDNode *createBranchWeights(uint64_t TrueCount, uint64_t FalseCount);
125 llvm::MDNode *createBranchWeights(ArrayRef<uint64_t> Weights);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000126 llvm::MDNode *createLoopWeights(const Stmt *Cond, RegionCounter &Cnt);
Justin Bogneref512b92014-01-06 22:27:43 +0000127
128 /// Assign counters to regions and configure them for PGO of a given
129 /// function. Does nothing if instrumentation is not enabled and either
130 /// generates global variables or associates PGO data with each of the
131 /// counters depending on whether we are generating or using instrumentation.
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000132 void assignRegionCounters(const Decl *D, llvm::Function *Fn);
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000133 /// Emit static data structures for instrumentation data.
134 void emitInstrumentationData();
Justin Bogneref512b92014-01-06 22:27:43 +0000135 /// Clean up region counter state. Must be called if assignRegionCounters is
136 /// used.
137 void destroyRegionCounters();
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000138 /// Emit static initialization code, if any.
Justin Bogneref512b92014-01-06 22:27:43 +0000139 static llvm::Function *emitInitialization(CodeGenModule &CGM);
140
141private:
Bob Wilsonda1ebed2014-03-06 04:55:41 +0000142 void setFuncName(llvm::Function *Fn);
Justin Bogneref512b92014-01-06 22:27:43 +0000143 void mapRegionCounters(const Decl *D);
Bob Wilsonbf854f02014-02-17 19:21:09 +0000144 void computeRegionCounts(const Decl *D);
Justin Bognerd66a17d2014-03-12 21:06:31 +0000145 void applyFunctionAttributes(PGOProfileData *PGOData, llvm::Function *Fn);
146 void loadRegionCounts(PGOProfileData *PGOData);
Justin Bogneref512b92014-01-06 22:27:43 +0000147 void emitCounterVariables();
Duncan P. N. Exon Smith2fe531c2014-03-17 21:18:30 +0000148 llvm::GlobalVariable *buildDataVar();
Justin Bogneref512b92014-01-06 22:27:43 +0000149
150 /// Emit code to increment the counter at the given index
151 void emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter);
152
153 /// Return the region counter for the given statement. This should only be
154 /// called on statements that have a dedicated counter.
155 unsigned getRegionCounter(const Stmt *S) {
156 if (RegionCounterMap == 0)
157 return 0;
158 return (*RegionCounterMap)[S];
159 }
160
161 /// Return the region count for the counter at the given index.
162 uint64_t getRegionCount(unsigned Counter) {
163 if (!haveRegionCounts())
164 return 0;
165 return (*RegionCounts)[Counter];
166 }
167
168 friend class RegionCounter;
169};
170
171/// A counter for a particular region. This is the primary interface through
172/// which clients manage PGO counters and their values.
173class RegionCounter {
174 CodeGenPGO *PGO;
175 unsigned Counter;
176 uint64_t Count;
177 uint64_t ParentCount;
178 uint64_t RegionCount;
179 int64_t Adjust;
180
181 RegionCounter(CodeGenPGO &PGO, unsigned CounterIndex)
182 : PGO(&PGO), Counter(CounterIndex), Count(PGO.getRegionCount(Counter)),
183 ParentCount(PGO.getCurrentRegionCount()), Adjust(0) {}
184
185public:
186 RegionCounter(CodeGenPGO &PGO, const Stmt *S)
187 : PGO(&PGO), Counter(PGO.getRegionCounter(S)),
188 Count(PGO.getRegionCount(Counter)),
189 ParentCount(PGO.getCurrentRegionCount()), Adjust(0) {}
190
191 /// Get the value of the counter. In most cases this is the number of times
192 /// the region of the counter was entered, but for switch labels it's the
193 /// number of direct jumps to that label.
194 uint64_t getCount() const { return Count; }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000195
Justin Bogneref512b92014-01-06 22:27:43 +0000196 /// Get the value of the counter with adjustments applied. Adjustments occur
Bob Wilsona7b16e02014-02-17 19:21:03 +0000197 /// when control enters or leaves the region abnormally; i.e., if there is a
Justin Bogneref512b92014-01-06 22:27:43 +0000198 /// jump to a label within the region, or if the function can return from
199 /// within the region. The adjusted count, then, is the value of the counter
200 /// at the end of the region.
201 uint64_t getAdjustedCount() const {
Justin Bogneref512b92014-01-06 22:27:43 +0000202 return Count + Adjust;
203 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000204
Bob Wilsona7b16e02014-02-17 19:21:03 +0000205 /// Get the value of the counter in this region's parent, i.e., the region
206 /// that was active when this region began. This is useful for deriving
207 /// counts in implicitly counted regions, like the false case of a condition
208 /// or the normal exits of a loop.
Justin Bogneref512b92014-01-06 22:27:43 +0000209 uint64_t getParentCount() const { return ParentCount; }
210
Justin Bogneref512b92014-01-06 22:27:43 +0000211 /// Activate the counter by emitting an increment and starting to track
212 /// adjustments. If AddIncomingFallThrough is true, the current region count
213 /// will be added to the counter for the purposes of tracking the region.
214 void beginRegion(CGBuilderTy &Builder, bool AddIncomingFallThrough=false) {
Bob Wilsonbf854f02014-02-17 19:21:09 +0000215 beginRegion(AddIncomingFallThrough);
216 PGO->emitCounterIncrement(Builder, Counter);
217 }
218 void beginRegion(bool AddIncomingFallThrough=false) {
Justin Bogneref512b92014-01-06 22:27:43 +0000219 RegionCount = Count;
220 if (AddIncomingFallThrough)
221 RegionCount += PGO->getCurrentRegionCount();
222 PGO->setCurrentRegionCount(RegionCount);
Justin Bogneref512b92014-01-06 22:27:43 +0000223 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000224
Justin Bogneref512b92014-01-06 22:27:43 +0000225 /// For counters on boolean branches, begins tracking adjustments for the
226 /// uncounted path.
227 void beginElseRegion() {
228 RegionCount = ParentCount - Count;
229 PGO->setCurrentRegionCount(RegionCount);
230 }
231
Bob Wilsonbf854f02014-02-17 19:21:09 +0000232 /// Reset the current region count.
233 void setCurrentRegionCount(uint64_t CurrentCount) {
234 RegionCount = CurrentCount;
235 PGO->setCurrentRegionCount(RegionCount);
236 }
237
Justin Bogner0718a3a2014-01-13 21:24:22 +0000238 /// Adjust for non-local control flow after emitting a subexpression or
239 /// substatement. This must be called to account for constructs such as gotos,
240 /// labels, and returns, so that we can ensure that our region's count is
241 /// correct in the code that follows.
242 void adjustForControlFlow() {
Justin Bogneref512b92014-01-06 22:27:43 +0000243 Adjust += PGO->getCurrentRegionCount() - RegionCount;
Bob Wilsonbf854f02014-02-17 19:21:09 +0000244 // Reset the region count in case this is called again later.
245 RegionCount = PGO->getCurrentRegionCount();
Justin Bogneref512b92014-01-06 22:27:43 +0000246 }
Bob Wilsonbf854f02014-02-17 19:21:09 +0000247
248 /// Commit all adjustments to the current region. If the region is a loop,
249 /// the LoopAdjust value should be the count of all the breaks and continues
250 /// from the loop, to compensate for those counts being deducted from the
251 /// adjustments for the body of the loop.
252 void applyAdjustmentsToRegion(uint64_t LoopAdjust) {
253 PGO->setCurrentRegionCount(ParentCount + Adjust + LoopAdjust);
Justin Bogneref512b92014-01-06 22:27:43 +0000254 }
255};
256
257} // end namespace CodeGen
258} // end namespace clang
259
260#endif