34 #define DEBUG_TYPE "misexpect" 37 using namespace misexpect;
45 cl::desc(
"Use this option to turn on/off " 46 "warnings about incorrect usage of llvm.expect intrinsics."));
53 assert(I !=
nullptr &&
"MisExpect target Instruction cannot be nullptr");
55 if (
auto *
B = dyn_cast<BranchInst>(I)) {
74 uint64_t ProfCount, uint64_t TotalCount) {
75 double PercentageCorrect = (double)ProfCount / TotalCount;
77 formatv(
"{0:P} ({1} / {2})", PercentageCorrect, ProfCount, TotalCount);
79 "Potential performance regression from use of the llvm.expect intrinsic: " 80 "Annotation was correct on {0} of profiled executions.",
97 if (
auto *MisExpectData = I->
getMetadata(LLVMContext::MD_misexpect)) {
99 if (MisExpectDataName &&
100 MisExpectDataName->getString().equals(
"misexpect")) {
106 llvm::dbgs() <<
"Weights[" << Idx <<
"] = " << Weights[Idx] <<
"\n";
110 const auto *IndexCint =
111 mdconst::dyn_extract<ConstantInt>(MisExpectData->getOperand(1));
112 const auto *LikelyCInt =
113 mdconst::dyn_extract<ConstantInt>(MisExpectData->getOperand(2));
114 const auto *UnlikelyCInt =
115 mdconst::dyn_extract<ConstantInt>(MisExpectData->getOperand(3));
117 if (!IndexCint || !LikelyCInt || !UnlikelyCInt)
120 const uint64_t
Index = IndexCint->getZExtValue();
124 const uint64_t CaseTotal = std::accumulate(
125 Weights.
begin(), Weights.
end(), (uint64_t)0, std::plus<uint64_t>());
126 const uint64_t NumUnlikelyTargets = Weights.
size() - 1;
128 const uint64_t TotalBranchWeight =
129 LikelyBranchWeight + (UnlikelyBranchWeight * NumUnlikelyTargets);
133 uint64_t ScaledThreshold = LikelyThreshold.scale(CaseTotal);
136 <<
"Unlikely Targets: " << NumUnlikelyTargets <<
":\n");
139 <<
"Scaled Threshold: " << ScaledThreshold <<
":\n");
141 if (ProfileCount < ScaledThreshold)
142 emitMisexpectDiagnostic(I, Ctx, ProfileCount, CaseTotal);
148 if (
auto *MD = I.
getMetadata(LLVMContext::MD_prof)) {
149 unsigned NOps = MD->getNumOperands();
161 if (
MDString *Tag = cast<MDString>(MD->getOperand(0))) {
162 if (Tag->getString().equals(
"branch_weights")) {
164 for (
unsigned i = 1; i < NOps; i++) {
166 mdconst::dyn_extract<ConstantInt>(MD->getOperand(i));
This class represents lattice values for constants.
LLVMContext & getContext() const
All values hold a context through their type.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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."))
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
void verifyMisExpect(llvm::Instruction *I, const llvm::SmallVector< uint32_t, 4 > &Weights, llvm::LLVMContext &Ctx)
verifyMisExpect - compares PGO counters to the thresholds used for llvm.expect and warns if the PGO c...
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)"))
initializer< Ty > init(const Ty &Val)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This is an important class for using LLVM in a threaded context.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Diagnostic information for MisExpect analysis.
const Function * getFunction() const
Return the function this instruction belongs to.
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)"))
Class to represent profile counts.
This is the shared class of boolean and integer constants.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
StringRef getName() const
Return a constant reference to the value's name.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
void checkFrontendInstrumentation(Instruction &I)
checkClangInstrumentation - verify if llvm.expect matches PGO profile This function checks the fronte...
const BasicBlock * getParent() const