36 cl::desc(
"Also inject (if missing) and verify MD_prof for "
37 "`select` instructions"));
40 cl::desc(
"Generate weights with small values for tests."));
43 "profcheck-default-select-true-weight",
cl::init(2U),
44 cl::desc(
"When annotating `select` instructions, this value will be used "
45 "for the first ('true') case."));
47 "profcheck-default-select-false-weight",
cl::init(3U),
48 cl::desc(
"When annotating `select` instructions, this value will be used "
49 "for the second ('false') case."));
51class ProfileInjector {
57 getTerminatorBenefitingFromMDProf(
const BasicBlock &BB) {
67 static Instruction *getTerminatorBenefitingFromMDProf(BasicBlock &BB) {
69 getTerminatorBenefitingFromMDProf(
const_cast<const BasicBlock &
>(BB)));
77 if (!
F.hasFnAttribute(Attribute::AttrKind::Naked))
79 for (
const auto &BB :
F)
82 if (!CB || !CB->isInlineAsm())
89 F.getContext().emitError(
"Profile verification failed for function '" +
90 F.getName() +
"': " + Msg);
97bool ProfileInjector::inject() {
119 if (!
F.getEntryCount(
true))
123 if (
F.getEntryCount(
true)->getCount() == 0)
129 uint32_t WeightsForTestOffset = 0;
134 if (
SI->getCondition()->getType()->isVectorTy())
136 if (
I.getMetadata(LLVMContext::MD_prof))
143 auto *
Term = getTerminatorBenefitingFromMDProf(BB);
144 if (!Term ||
Term->getMetadata(LLVMContext::MD_prof))
146 SmallVector<BranchProbability> Probs;
148 SmallVector<uint32_t> Weights;
151 static const std::array Primes{3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
152 37, 41, 43, 47, 53, 59, 61, 67, 71};
153 for (uint32_t
I = 0,
E =
Term->getNumSuccessors();
I <
E; ++
I)
155 Primes[(WeightsForTestOffset +
I) % Primes.size()]);
156 ++WeightsForTestOffset;
159 for (
auto I = 0U,
E =
Term->getNumSuccessors();
I <
E; ++
I)
163 [](
const BranchProbability &
P) {
164 return P.isUnknown();
166 "All branch probabilities should be valid");
167 const auto *FirstZeroDenominator =
168 find_if(Probs, [](
const BranchProbability &
P) {
169 return P.getDenominator() == 0;
171 (void)FirstZeroDenominator;
172 assert(FirstZeroDenominator == Probs.
end());
173 const auto *FirstNonZeroNumerator =
find_if(
174 Probs, [](
const BranchProbability &
P) {
return !
P.isZero(); });
175 assert(FirstNonZeroNumerator != Probs.
end());
176 DynamicAPInt LCM(Probs[0].getDenominator());
177 DynamicAPInt GCD(FirstNonZeroNumerator->getNumerator());
179 if (!Prob.getNumerator())
181 LCM =
llvm::lcm(LCM, DynamicAPInt(Prob.getDenominator()));
182 GCD =
llvm::gcd(GCD, DynamicAPInt(Prob.getNumerator()));
184 for (
const auto &Prob : Probs) {
186 (Prob.getNumerator() * LCM / GCD) / Prob.getDenominator();
187 Weights.
emplace_back(
static_cast<uint32_t
>((int64_t)W));
198 ProfileInjector PI(
F,
FAM);
207 auto PopulateIgnoreList = [&](
StringRef GVName) {
208 if (
const auto *CT = M.getGlobalVariable(GVName))
211 for (
const auto &Elt : CA->operands())
213 if (CS->getNumOperands() >= 2 && CS->getOperand(1))
215 CS->getOperand(1)->stripPointerCasts()))
216 IgnoreList.insert(
F);
218 PopulateIgnoreList(
"llvm.global_ctors");
219 PopulateIgnoreList(
"llvm.global_dtors");
227 return PVP.run(
F,
FAM);
240 if (IgnoreList.contains(&
F))
243 const auto EntryCount =
F.getEntryCount(
true);
245 auto *MD =
F.getMetadata(LLVMContext::MD_prof);
247 emitProfileError(
"function entry count missing (set to 0 if cold)",
F);
250 }
else if (EntryCount->getCount() == 0) {
253 for (
const auto &BB :
F) {
255 for (
const auto &
I : BB)
257 if (
SI->getCondition()->getType()->isVectorTy())
259 if (
I.getMetadata(LLVMContext::MD_prof))
261 emitProfileError(
"select annotation missing",
F);
264 if (
const auto *Term =
265 ProfileInjector::getTerminatorBenefitingFromMDProf(BB))
266 if (!
Term->getMetadata(LLVMContext::MD_prof))
267 emitProfileError(
"branch annotation missing",
F);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
This file contains the declarations for profiling metadata utility functions.
static cl::opt< bool > WeightsForTest("profcheck-weights-for-test", cl::init(false), cl::desc("Generate weights with small values for tests."))
static cl::opt< uint32_t > SelectFalseWeight("profcheck-default-select-false-weight", cl::init(3U), cl::desc("When annotating `select` instructions, this value will be used " "for the second ('false') case."))
static cl::opt< int64_t > DefaultFunctionEntryCount("profcheck-default-function-entry-count", cl::init(1000))
static cl::opt< bool > AnnotateSelect("profcheck-annotate-select", cl::init(true), cl::desc("Also inject (if missing) and verify MD_prof for " "`select` instructions"))
static cl::opt< uint32_t > SelectTrueWeight("profcheck-default-select-true-weight", cl::init(2U), cl::desc("When annotating `select` instructions, this value will be used " "for the first ('true') case."))
This file defines the SmallString class.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
LLVM_ABI iterator_range< filter_iterator< BasicBlock::const_iterator, std::function< bool(const Instruction &)> > > instructionsWithoutDebug(bool SkipPseudoOp=true) const
Return a const iterator range over the instructions in the block, skipping any debug instructions.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Runs the function pass across every function in the module.
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Checks that MD_prof is present on every instruction that supports it.
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
StringRef - Represent a constant reference to a string, i.e.
Pass manager infrastructure for declaring and invalidating analyses.
@ BasicBlock
Various leaf nodes.
initializer< Ty > init(const Ty &Val)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
ModuleToFunctionPassAdaptor createModuleToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
LLVM_ABI bool isExplicitlyUnknownProfileMetadata(const MDNode &MD)
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected, bool ElideAllZero=false)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
auto succ_size(const MachineBasicBlock *BB)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt lcm(const DynamicAPInt &A, const DynamicAPInt &B)
Returns the least common multiple of A and B.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
A CRTP mix-in to automatically provide informational APIs needed for passes.