LLVM: lib/Transforms/Utils/MisExpect.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
41#include
42#include
43#include
44#include
45
46#define DEBUG_TYPE "misexpect"
47
48using namespace llvm;
49using namespace misexpect;
50
51namespace llvm {
52
53
54
57 cl::desc("Use this option to turn on/off "
58 "warnings about incorrect usage of llvm.expect intrinsics."));
59
60
62 "misexpect-tolerance", cl::init(0),
63 cl::desc("Prevents emitting diagnostics when profile counts are "
64 "within N% of the threshold.."));
65
66}
67
68namespace {
69
70bool isMisExpectDiagEnabled(LLVMContext &Ctx) {
72}
73
77}
78
80 assert(I != nullptr && "MisExpect target Instruction cannot be nullptr");
82 if (auto *B = dyn_cast(I)) {
83 Ret = dyn_cast(B->getCondition());
84 }
85
86
87
88
89
90
91
92
93
94 else if (auto *S = dyn_cast(I)) {
95 Ret = dyn_cast(S->getCondition());
96 }
98}
99
102 double PercentageCorrect = (double)ProfCount / TotalCount;
103 auto PerString =
104 formatv("{0:P} ({1} / {2})", PercentageCorrect, ProfCount, TotalCount);
106 "Potential performance regression from use of the llvm.expect intrinsic: "
107 "Annotation was correct on {0} of profiled executions.",
108 PerString);
109 Twine Msg(PerString);
111 if (isMisExpectDiagEnabled(Ctx))
115}
116
117}
118
119namespace llvm {
120namespace misexpect {
121
124
125
126
127
128
131 size_t MaxIndex = 0;
136 MaxIndex = Idx;
137 }
140 }
141 }
142
143 const uint64_t ProfiledWeight = RealWeights[MaxIndex];
144 const uint64_t RealWeightsTotal =
145 std::accumulate(RealWeights.begin(), RealWeights.end(), (uint64_t)0,
146 std::plus<uint64_t>());
147 const uint64_t NumUnlikelyTargets = RealWeights.size() - 1;
148
151
152
154 "TotalBranchWeight is less than the Likely branch weight");
155
156
157
158
161
162 uint64_t ScaledThreshold = LikelyProbablilty.scale(RealWeightsTotal);
163
164
165 auto Tolerance = getMisExpectTolerance(I.getContext());
166 Tolerance = std::clamp(Tolerance, 0u, 99u);
167
168
169
170 if (Tolerance > 0)
171 ScaledThreshold *= (1.0 - Tolerance / 100.0);
172
173
174 if (ProfiledWeight < ScaledThreshold)
175 emitMisexpectDiagnostic(&I, I.getContext(), ProfiledWeight,
176 RealWeightsTotal);
177}
178
181
182
183
184
185
187 return;
190 return;
192}
193
198 return;
200}
201
204 bool IsFrontend) {
205 if (IsFrontend) {
207 } else {
209 }
210}
211
212}
213}
214#undef DEBUG_TYPE
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static cl::opt< uint32_t > UnlikelyBranchWeight("unlikely-branch-weight", cl::Hidden, cl::init(1), cl::desc("Weight of the branch unlikely to be taken (default = 1)"))
static cl::opt< uint32_t > LikelyBranchWeight("likely-branch-weight", cl::Hidden, cl::init(2000), cl::desc("Weight of the branch likely to be taken (default = 2000)"))
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
static BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
Diagnostic information for MisExpect analysis.
This is an important class for using LLVM in a threaded context.
bool getMisExpectWarningRequested() const
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
uint32_t getDiagnosticsMisExpectTolerance() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
initializer< Ty > init(const Ty &Val)
void checkFrontendInstrumentation(Instruction &I, const ArrayRef< uint32_t > ExpectedWeights)
checkFrontendInstrumentation - compares PGO counters to the thresholds used for llvm....
void checkExpectAnnotations(Instruction &I, const ArrayRef< uint32_t > ExistingWeights, bool IsFrontend)
checkExpectAnnotations - compares PGO counters to the thresholds used for llvm.expect and warns if th...
void checkBackendInstrumentation(Instruction &I, const llvm::ArrayRef< uint32_t > RealWeights)
checkBackendInstrumentation - compares PGO counters to the thresholds used for llvm....
void verifyMisExpect(Instruction &I, ArrayRef< uint32_t > RealWeights, const ArrayRef< uint32_t > ExpectedWeights)
veryifyMisExpect - compares RealWeights to the thresholds used for llvm.expect and warns if the PGO c...
This is an optimization pass for GlobalISel generic memory operations.
static cl::opt< bool > PGOWarnMisExpect("pgo-warn-misexpect", cl::init(false), cl::Hidden, cl::desc("Use this option to turn on/off " "warnings about incorrect usage of llvm.expect intrinsics."))
bool hasBranchWeightOrigin(const Instruction &I)
Check if Branch Weight Metadata has an "expected" field from an llvm.expect* intrinsic.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
static cl::opt< uint32_t > MisExpectTolerance("misexpect-tolerance", cl::init(0), cl::desc("Prevents emitting diagnostics when profile counts are " "within N% of the threshold.."))
bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.