Go to the documentation of this file.
46 #define DEBUG_TYPE "misexpect"
49 using namespace misexpect;
57 cl::desc(
"Use this option to turn on/off "
58 "warnings about incorrect usage of llvm.expect intrinsics."));
62 cl::desc(
"Prevents emiting diagnostics when profile counts are "
63 "within N% of the threshold.."));
79 assert(
I !=
nullptr &&
"MisExpect target Instruction cannot be nullptr");
81 if (
auto *
B = dyn_cast<BranchInst>(
I)) {
82 Ret = dyn_cast<Instruction>(
B->getCondition());
93 else if (
auto *
S = dyn_cast<SwitchInst>(
I)) {
94 Ret = dyn_cast<Instruction>(
S->getCondition());
101 double PercentageCorrect = (
double)ProfCount / TotalCount;
103 formatv(
"{0:P} ({1} / {2})", PercentageCorrect, ProfCount, TotalCount);
105 "Potential performance regression from use of the llvm.expect intrinsic: "
106 "Annotation was correct on {0} of profiled executions.",
110 if (isMisExpectDiagEnabled(Ctx))
119 namespace misexpect {
124 assert(
I &&
"MisExpect::extractWeights given invalid pointer");
126 auto *ProfileData =
I->getMetadata(LLVMContext::MD_prof);
130 unsigned NOps = ProfileData->getNumOperands();
134 auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(0));
135 if (!ProfDataName || !ProfDataName->getString().equals(
"branch_weights"))
139 for (
unsigned Idx = 1; Idx < NOps; Idx++) {
141 mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(Idx));
143 Weights[Idx - 1] = V;
168 for (
size_t Idx = 0, End = ExpectedWeights.
size(); Idx < End; Idx++) {
179 const uint64_t ProfiledWeight = RealWeights[MaxIndex];
182 std::plus<uint64_t>());
183 const uint64_t NumUnlikelyTargets = RealWeights.
size() - 1;
202 uint64_t ScaledThreshold = LikelyProbablilty.scale(RealWeightsTotal);
205 auto Tolerance = getMisExpectTolerance(
I.getContext());
206 Tolerance =
clamp(Tolerance, 0, 99);
211 ScaledThreshold *= (1.0 - Tolerance / 100.0);
214 if (ProfiledWeight < ScaledThreshold)
215 emitMisexpectDiagnostic(&
I,
I.getContext(), ProfiledWeight,
222 if (!ExpectedWeightsOpt.hasValue())
224 auto ExpectedWeights = ExpectedWeightsOpt.getValue();
231 if (!RealWeightsOpt.hasValue())
233 auto RealWeights = RealWeightsOpt.getValue();
239 bool IsFrontendInstr) {
240 if (IsFrontendInstr) {
void checkFrontendInstrumentation(Instruction &I, const ArrayRef< uint32_t > ExpectedWeights)
checkFrontendInstrumentation - compares PGO counters to the thresholds used for llvm....
This is an optimization pass for GlobalISel generic memory operations.
bool getMisExpectWarningRequested() const
uint64_t getDiagnosticsMisExpectTolerance() const
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions main should enable SSE DAZ mode and other fast SSE modes Think about doing i64 math in SSE regs on x86 This testcase should have no SSE instructions in and only one load from a constant double
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."))
static BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
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)"))
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
This is the shared class of boolean and integer constants.
Optional< SmallVector< uint32_t, 4 > > extractWeights(Instruction *I, LLVMContext &Ctx)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Diagnostic information for MisExpect analysis.
This is an important class for using LLVM in a threaded context.
static cl::opt< unsigned > MisExpectTolerance("misexpect-tolerance", cl::init(0), cl::desc("Prevents emiting diagnostics when profile counts are " "within N% of the threshold.."))
initializer< Ty > init(const Ty &Val)
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...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)"))
void checkBackendInstrumentation(Instruction &I, const llvm::ArrayRef< uint32_t > RealWeights)
checkBackendInstrumentation - compares PGO counters to the thresholds used for llvm....
SmallVector< MachineOperand, 4 > Cond
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
const CustomOperand< const MCSubtargetInfo & > Msg[]
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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...
uint32_t clamp(uint64_t value, uint32_t low, uint32_t hi)
size_t size() const
size - Get the array size.
LLVM Value Representation.