57 using namespace sampleprof;
59 #define DEBUG_TYPE "sample-profile"
67 "sample-profile-max-propagate-iterations",
cl::init(100),
68 cl::desc(
"Maximum number of iterations to go through when propagating "
69 "sample block/edge weights through the CFG."));
72 cl::desc(
"Emit a warning if less than N% of records in the input profile "
73 "are matched to the IR."));
76 cl::desc(
"Emit a warning if less than N% of samples in the input profile "
77 "are matched to the IR."));
80 cl::desc(
"Inlined functions that account for more than N% of all samples "
81 "collected in the parent function, will be inlined again."));
86 typedef std::pair<const BasicBlock *, const BasicBlock *> Edge;
91 class SampleCoverageTracker {
93 SampleCoverageTracker() : SampleCoverage(), TotalUsedSamples(0) {}
96 uint32_t Discriminator, uint64_t Samples);
97 unsigned computeCoverage(
unsigned Used,
unsigned Total)
const;
100 uint64_t getTotalUsedSamples()
const {
return TotalUsedSamples; }
103 SampleCoverage.clear();
104 TotalUsedSamples = 0;
108 typedef std::map<LineLocation, unsigned> BodySampleCoverageMap;
110 FunctionSamplesCoverageMap;
121 FunctionSamplesCoverageMap SampleCoverage;
134 uint64_t TotalUsedSamples;
142 class SampleProfileLoader {
145 : DT(nullptr), PDT(nullptr), LI(nullptr), ACT(nullptr), Reader(),
146 Samples(nullptr), Filename(
Name), ProfileIsValid(
false),
147 TotalCollectedSamples(0) {}
149 bool doInitialization(
Module &M);
150 bool runOnModule(
Module &M);
153 void dump() { Reader->dump(); }
168 void findEquivalenceClasses(
Function &
F);
172 uint64_t visitEdge(Edge
E,
unsigned *NumUnknownEdges, Edge *UnknownEdge);
174 bool propagateThroughEdges(
Function &
F,
bool UpdateBlockCount);
175 void computeDominanceAndLoopInfo(
Function &
F);
177 void clearFunctionData();
183 BlockWeightMap BlockWeights;
189 EdgeWeightMap EdgeWeights;
203 EquivalenceClassMap EquivalenceClass;
206 std::unique_ptr<DominatorTree> DT;
207 std::unique_ptr<DominatorTreeBase<BasicBlock>> PDT;
208 std::unique_ptr<LoopInfo> LI;
213 BlockEdgeMap Predecessors;
216 BlockEdgeMap Successors;
218 SampleCoverageTracker CoverageTracker;
221 std::unique_ptr<SampleProfileReader> Reader;
227 std::string Filename;
236 uint64_t TotalCollectedSamples;
239 class SampleProfileLoaderLegacyPass :
public ModulePass {
250 void dump() { SampleLoader.dump(); }
252 bool doInitialization(
Module &M)
override {
253 return SampleLoader.doInitialization(M);
255 StringRef getPassName()
const override {
return "Sample profile pass"; }
256 bool runOnModule(
Module &M)
override;
263 SampleProfileLoader SampleLoader;
286 if (ParentTotalSamples == 0)
290 if (CallsiteTotalSamples == 0)
293 double PercentSamples =
294 (double)CallsiteTotalSamples / (
double)ParentTotalSamples * 100.0;
308 unsigned &Count = SampleCoverage[FS][Loc];
309 bool FirstTime = (++Count == 1);
311 TotalUsedSamples += Samples;
319 SampleCoverageTracker::countUsedRecords(
const FunctionSamples *FS)
const {
320 auto I = SampleCoverage.find(FS);
324 unsigned Count = (
I != SampleCoverage.end()) ?
I->second.size() : 0;
331 if (callsiteIsHot(FS, CalleeSamples))
332 Count += countUsedRecords(CalleeSamples);
342 SampleCoverageTracker::countBodyRecords(
const FunctionSamples *FS)
const {
348 if (callsiteIsHot(FS, CalleeSamples))
349 Count += countBodyRecords(CalleeSamples);
359 SampleCoverageTracker::countBodySamples(
const FunctionSamples *FS)
const {
362 Total +=
I.second.getSamples();
367 if (callsiteIsHot(FS, CalleeSamples))
368 Total += countBodySamples(CalleeSamples);
379 unsigned SampleCoverageTracker::computeCoverage(
unsigned Used,
380 unsigned Total)
const {
382 "number of used records cannot exceed the total number of records");
383 return Total > 0 ? Used * 100 / Total : 100;
387 void SampleProfileLoader::clearFunctionData() {
388 BlockWeights.clear();
390 VisitedBlocks.clear();
391 VisitedEdges.clear();
392 EquivalenceClass.clear();
396 Predecessors.clear();
398 CoverageTracker.clear();
409 return (L - H) & 0xffff;
416 void SampleProfileLoader::printEdgeWeight(
raw_ostream &OS, Edge
E) {
417 OS <<
"weight[" << E.first->getName() <<
"->" << E.second->getName()
418 <<
"]: " << EdgeWeights[
E] <<
"\n";
425 void SampleProfileLoader::printBlockEquivalence(
raw_ostream &OS,
427 const BasicBlock *Equiv = EquivalenceClass[BB];
428 OS <<
"equivalence[" << BB->
getName()
429 <<
"]: " << ((Equiv) ? EquivalenceClass[BB]->
getName() :
"NONE") <<
"\n";
436 void SampleProfileLoader::printBlockWeight(
raw_ostream &OS,
438 const auto &
I = BlockWeights.find(BB);
439 uint64_t W = (
I == BlockWeights.end() ? 0 :
I->second);
440 OS <<
"weight[" << BB->
getName() <<
"]: " << W <<
"\n";
455 SampleProfileLoader::getInstWeight(
const Instruction &Inst) {
458 return std::error_code();
462 return std::error_code();
467 if (isa<BranchInst>(Inst) || isa<IntrinsicInst>(Inst))
468 return std::error_code();
473 bool IsCall = isa<CallInst>(Inst) || isa<InvokeInst>(Inst);
474 if (IsCall && findCalleeFunctionSamples(Inst))
478 unsigned Lineno = DLoc.
getLine();
479 unsigned HeaderLineno = DIL->getScope()->getSubprogram()->getLine();
482 uint32_t Discriminator = DIL->getDiscriminator();
488 CoverageTracker.markSamplesUsed(FS, LineOffset, Discriminator, R.
get());
494 Twine(
"Applied ") +
Twine(*R) +
" samples from profile (offset: " +
496 ((Discriminator) ?
Twine(
".") +
Twine(Discriminator) :
"") +
")");
498 DEBUG(
dbgs() <<
" " << Lineno <<
"." << DIL->getDiscriminator() <<
":"
499 << Inst <<
" (line offset: " << Lineno - HeaderLineno <<
"."
500 << DIL->getDiscriminator() <<
" - weight: " << R.
get()
515 SampleProfileLoader::getBlockWeight(
const BasicBlock *BB) {
517 bool HasWeight =
false;
521 Max = std::max(Max, R.
get());
534 bool SampleProfileLoader::computeBlockWeights(
Function &F) {
535 bool Changed =
false;
537 for (
const auto &BB : F) {
540 BlockWeights[&BB] = Weight.
get();
541 VisitedBlocks.insert(&BB);
563 SampleProfileLoader::findCalleeFunctionSamples(
const Instruction &Inst)
const {
577 getOffset(DIL->getLine(), SP->getLine()), DIL->getDiscriminator()));
590 SampleProfileLoader::findFunctionSamples(
const Instruction &Inst)
const {
596 for (DIL = DIL->getInlinedAt(); DIL; DIL = DIL->getInlinedAt()) {
601 DIL->getDiscriminator()));
606 for (
int i = S.
size() - 1;
i >= 0 && FS !=
nullptr;
i--) {
624 bool SampleProfileLoader::inlineHotFunctions(
Function &F) {
625 bool Changed =
false;
627 std::function<AssumptionCache &(Function &)> GetAssumptionCache = [&](
630 bool LocalChanged =
false;
637 if ((isa<CallInst>(
I) || isa<InvokeInst>(
I)) &&
638 (FS = findCalleeFunctionSamples(
I))) {
640 if (callsiteIsHot(Samples, FS))
651 Function *CalledFunction =
CS.getCalledFunction();
655 uint64_t NumSamples = findCalleeFunctionSamples(*I)->getTotalSamples();
659 Twine(
"inlined hot callee '") +
660 CalledFunction->
getName() +
"' with " +
661 Twine(NumSamples) +
" samples into '" +
697 void SampleProfileLoader::findEquivalencesFor(
701 uint64_t Weight = BlockWeights[EC];
702 for (
const auto *BB2 : Descendants) {
703 bool IsDomParent = DomTree->
dominates(BB2, BB1);
704 bool IsInSameLoop = LI->getLoopFor(BB1) == LI->getLoopFor(BB2);
705 if (BB1 != BB2 && IsDomParent && IsInSameLoop) {
706 EquivalenceClass[BB2] = EC;
708 if (VisitedBlocks.count(BB2)) {
709 VisitedBlocks.insert(EC);
720 Weight = std::max(Weight, BlockWeights[BB2]);
724 BlockWeights[EC] = Samples->getHeadSamples() + 1;
726 BlockWeights[EC] = Weight;
739 void SampleProfileLoader::findEquivalenceClasses(
Function &F) {
741 DEBUG(
dbgs() <<
"\nBlock equivalence classes\n");
747 if (EquivalenceClass.count(BB1)) {
748 DEBUG(printBlockEquivalence(
dbgs(), BB1));
753 EquivalenceClass[BB1] = BB1;
765 DominatedBBs.
clear();
766 DT->getDescendants(BB1, DominatedBBs);
767 findEquivalencesFor(BB1, DominatedBBs, PDT.get());
769 DEBUG(printBlockEquivalence(
dbgs(), BB1));
778 DEBUG(
dbgs() <<
"\nAssign the same weight to all blocks in the same class\n");
781 const BasicBlock *EquivBB = EquivalenceClass[BB];
783 BlockWeights[BB] = BlockWeights[EquivBB];
798 uint64_t SampleProfileLoader::visitEdge(Edge E,
unsigned *NumUnknownEdges,
800 if (!VisitedEdges.count(E)) {
801 (*NumUnknownEdges)++;
806 return EdgeWeights[
E];
822 bool SampleProfileLoader::propagateThroughEdges(
Function &F,
823 bool UpdateBlockCount) {
824 bool Changed =
false;
825 DEBUG(
dbgs() <<
"\nPropagation through edges\n");
826 for (
const auto &BI : F) {
835 for (
unsigned i = 0;
i < 2;
i++) {
836 uint64_t TotalWeight = 0;
837 unsigned NumUnknownEdges = 0, NumTotalEdges = 0;
838 Edge UnknownEdge, SelfReferentialEdge, SingleEdge;
842 NumTotalEdges = Predecessors[BB].size();
843 for (
auto *Pred : Predecessors[BB]) {
844 Edge E = std::make_pair(Pred, BB);
845 TotalWeight += visitEdge(E, &NumUnknownEdges, &UnknownEdge);
846 if (E.first == E.second)
847 SelfReferentialEdge =
E;
849 if (NumTotalEdges == 1) {
850 SingleEdge = std::make_pair(Predecessors[BB][0], BB);
854 NumTotalEdges = Successors[BB].size();
855 for (
auto *Succ : Successors[BB]) {
856 Edge E = std::make_pair(BB, Succ);
857 TotalWeight += visitEdge(E, &NumUnknownEdges, &UnknownEdge);
859 if (NumTotalEdges == 1) {
860 SingleEdge = std::make_pair(BB, Successors[BB][0]);
887 if (NumUnknownEdges <= 1) {
888 uint64_t &BBWeight = BlockWeights[EC];
889 if (NumUnknownEdges == 0) {
890 if (!VisitedBlocks.count(EC)) {
894 if (TotalWeight > BBWeight) {
895 BBWeight = TotalWeight;
897 DEBUG(
dbgs() <<
"All edge weights for " << BB->getName()
898 <<
" known. Set weight for block: ";
899 printBlockWeight(
dbgs(), BB););
901 }
else if (NumTotalEdges == 1 &&
902 EdgeWeights[SingleEdge] < BlockWeights[EC]) {
905 EdgeWeights[SingleEdge] = BlockWeights[EC];
908 }
else if (NumUnknownEdges == 1 && VisitedBlocks.count(EC)) {
911 if (BBWeight >= TotalWeight)
912 EdgeWeights[UnknownEdge] = BBWeight - TotalWeight;
914 EdgeWeights[UnknownEdge] = 0;
917 OtherEC = EquivalenceClass[UnknownEdge.first];
919 OtherEC = EquivalenceClass[UnknownEdge.second];
921 if (VisitedBlocks.count(OtherEC) &&
922 EdgeWeights[UnknownEdge] > BlockWeights[OtherEC])
923 EdgeWeights[UnknownEdge] = BlockWeights[OtherEC];
924 VisitedEdges.insert(UnknownEdge);
927 printEdgeWeight(
dbgs(), UnknownEdge));
929 }
else if (VisitedBlocks.count(EC) && BlockWeights[EC] == 0) {
932 for (
auto *Pred : Predecessors[BB]) {
933 Edge E = std::make_pair(Pred, BB);
935 VisitedEdges.insert(E);
938 for (
auto *Succ : Successors[BB]) {
939 Edge E = std::make_pair(BB, Succ);
941 VisitedEdges.insert(E);
944 }
else if (SelfReferentialEdge.first && VisitedBlocks.count(EC)) {
945 uint64_t &BBWeight = BlockWeights[BB];
947 if (BBWeight >= TotalWeight)
948 EdgeWeights[SelfReferentialEdge] = BBWeight - TotalWeight;
950 EdgeWeights[SelfReferentialEdge] = 0;
951 VisitedEdges.insert(SelfReferentialEdge);
953 DEBUG(
dbgs() <<
"Set self-referential edge weight to: ";
954 printEdgeWeight(
dbgs(), SelfReferentialEdge));
956 if (UpdateBlockCount && !VisitedBlocks.count(EC) && TotalWeight > 0) {
957 BlockWeights[EC] = TotalWeight;
958 VisitedBlocks.insert(EC);
971 void SampleProfileLoader::buildEdges(
Function &F) {
977 if (!Predecessors[B1].empty())
981 if (Visited.
insert(B2).second)
982 Predecessors[B1].push_back(B2);
987 if (!Successors[B1].empty())
991 if (Visited.
insert(B2).second)
992 Successors[B1].push_back(B2);
1014 void SampleProfileLoader::propagateWeights(
Function &F) {
1015 bool Changed =
true;
1024 for (
auto &BI : F) {
1026 Loop *L = LI->getLoopFor(BB);
1031 if (Header && BlockWeights[BB] > BlockWeights[Header]) {
1032 BlockWeights[Header] = BlockWeights[BB];
1045 Changed = propagateThroughEdges(F,
false);
1051 VisitedEdges.clear();
1054 Changed = propagateThroughEdges(F,
false);
1061 Changed = propagateThroughEdges(F,
true);
1066 DEBUG(
dbgs() <<
"\nPropagation complete. Setting branch weights\n");
1069 for (
auto &BI : F) {
1072 if (BlockWeights[BB]) {
1073 for (
auto &I : BB->getInstList()) {
1074 if (
CallInst *CI = dyn_cast<CallInst>(&I)) {
1075 if (!dyn_cast<IntrinsicInst>(&I)) {
1079 MDB.createBranchWeights(Weights));
1087 if (!isa<BranchInst>(TI) && !isa<SwitchInst>(TI))
1090 DEBUG(
dbgs() <<
"\nGetting weights for branch at line "
1097 Edge E = std::make_pair(BB, Succ);
1098 uint64_t Weight = EdgeWeights[
E];
1103 if (Weight > std::numeric_limits<uint32_t>::max()) {
1104 DEBUG(
dbgs() <<
" (saturated due to uint32_t overflow)");
1105 Weight = std::numeric_limits<uint32_t>::max();
1109 Weights.push_back(static_cast<uint32_t>(Weight + 1));
1111 if (Weight > MaxWeight) {
1120 if (MaxWeight > 0) {
1121 DEBUG(
dbgs() <<
"SUCCESS. Found non-zero weights.\n");
1123 MDB.createBranchWeights(Weights));
1127 Twine(
"most popular destination for conditional branches at ") +
1128 ((BranchLoc) ?
Twine(BranchLoc->getFilename() +
":" +
1131 :
Twine(
"<UNKNOWN LOCATION>")));
1133 DEBUG(
dbgs() <<
"SKIPPED. All branch weights are zero.\n");
1149 unsigned SampleProfileLoader::getFunctionLoc(
Function &F) {
1151 return S->getLine();
1156 "No debug information found in function " + F.
getName() +
1157 ": Function profile not used",
1162 void SampleProfileLoader::computeDominanceAndLoopInfo(
Function &F) {
1167 PDT->recalculate(F);
1222 bool SampleProfileLoader::emitAnnotations(
Function &F) {
1223 bool Changed =
false;
1225 if (getFunctionLoc(F) == 0)
1229 <<
": " << getFunctionLoc(F) <<
"\n");
1231 Changed |= inlineHotFunctions(F);
1234 Changed |= computeBlockWeights(F);
1238 computeDominanceAndLoopInfo(F);
1241 findEquivalenceClasses(F);
1244 propagateWeights(F);
1249 unsigned Used = CoverageTracker.countUsedRecords(Samples);
1250 unsigned Total = CoverageTracker.countBodyRecords(Samples);
1251 unsigned Coverage = CoverageTracker.computeCoverage(Used, Total);
1255 Twine(Used) +
" of " +
Twine(Total) +
" available profile records (" +
1256 Twine(Coverage) +
"%) were applied",
1262 uint64_t Used = CoverageTracker.getTotalUsedSamples();
1263 uint64_t Total = CoverageTracker.countBodySamples(Samples);
1264 unsigned Coverage = CoverageTracker.computeCoverage(Used, Total);
1268 Twine(Used) +
" of " +
Twine(Total) +
" available profile samples (" +
1269 Twine(Coverage) +
"%) were applied",
1278 "Sample Profile loader",
false,
false)
1283 bool SampleProfileLoader::doInitialization(
Module &M) {
1284 auto &Ctx = M.getContext();
1286 if (std::error_code EC = ReaderOrErr.getError()) {
1287 std::string Msg =
"Could not open profile: " + EC.message();
1291 Reader = std::move(ReaderOrErr.get());
1301 return new SampleProfileLoaderLegacyPass(Name);
1304 bool SampleProfileLoader::runOnModule(
Module &M) {
1305 if (!ProfileIsValid)
1309 for (
const auto &I : Reader->getProfiles())
1310 TotalCollectedSamples += I.second.getTotalSamples();
1312 bool retval =
false;
1315 clearFunctionData();
1316 retval |= runOnFunction(F);
1318 if (M.getProfileSummary() ==
nullptr)
1319 M.setProfileSummary(Reader->getSummary().getMD(M.getContext()));
1323 bool SampleProfileLoaderLegacyPass::runOnModule(
Module &M) {
1325 SampleLoader.setACT(&getAnalysis<AssumptionCacheTracker>());
1326 return SampleLoader.runOnModule(M);
1329 bool SampleProfileLoader::runOnFunction(
Function &F) {
1331 Samples = Reader->getSamplesFor(F);
1332 if (!Samples->empty())
1333 return emitAnnotations(F);
1342 SampleLoader.doInitialization(M);
1344 if (!SampleLoader.runOnModule(M))
void push_back(const T &Elt)
Represents either an error or a value T.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
const BodySampleMap & getBodySamples() const
Return all the samples collected in the body of the function.
A Module instance is used to store all the information related to an LLVM module. ...
This class represents a function call, abstracting a target machine's calling convention.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of .assume calls within a function.
static ErrorOr< std::unique_ptr< SampleProfileReader > > create(const Twine &Filename, LLVMContext &C)
Create a sample profile reader appropriate to the file format.
const Function * getParent() const
Return the enclosing method, or null if none.
const FunctionSamples * findFunctionSamplesAt(const LineLocation &Loc) const
Return a pointer to function samples at the given callsite location.
InlineFunctionInfo - This class captures the data input to the InlineFunction call, and records the auxiliary results produced by it.
void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit an optimization-applied message.
BlockT * getHeader() const
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
StringRef getName() const
Return a constant reference to the value's name.
Representation of the samples collected for a function.
bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI, AAResults *CalleeAAR=nullptr, bool InsertLifetime=true)
InlineFunction - This function inlines the called function into the basic block of the caller...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static StringRef getName(Value *V)
StringRef getFilename() const
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
ErrorOr< uint64_t > findCallSamplesAt(uint32_t LineOffset, uint32_t Discriminator) const
Return the total number of call target samples collected at a given location.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
static cl::opt< std::string > SampleProfileFile("sample-profile-file", cl::init(""), cl::value_desc("filename"), cl::desc("Profile file loaded by -sample-profile"), cl::Hidden)
ModulePass * createSampleProfileLoaderPass()
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
Interval::succ_iterator succ_end(Interval *I)
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
initializer< Ty > init(const Ty &Val)
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Subclasses of this class are all able to terminate a basic block.
A set of analyses that are preserved following a run of a transformation pass.
LLVM Basic Block Representation.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
BasicBlock * getSuccessor(unsigned idx) const
Return the specified successor.
This is an important class for using LLVM in a threaded context.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Represent the analysis usage information of a pass.
const InstListType & getInstList() const
Return the underlying instruction list container.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
Interval::pred_iterator pred_end(Interval *I)
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
void initializeSampleProfileLoaderLegacyPassPass(PassRegistry &)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Instruction * getFirstNonPHIOrDbgOrLifetime()
Returns a pointer to the first instruction in this block that is not a PHINode, a debug intrinsic...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
void setEntryCount(uint64_t Count)
Set the entry count for this function.
const CallsiteSampleMap & getCallsiteSamples() const
Return all the callsite samples collected in the body of the function.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static cl::opt< unsigned > SampleProfileRecordCoverage("sample-profile-check-record-coverage", cl::init(0), cl::value_desc("N"), cl::desc("Emit a warning if less than N% of records in the input profile ""are matched to the IR."))
Module.h This file contains the declarations for the Module class.
const BasicBlock & getEntryBlock() const
static cl::opt< unsigned > SampleProfileMaxPropagateIterations("sample-profile-max-propagate-iterations", cl::init(100), cl::desc("Maximum number of iterations to go through when propagating ""sample block/edge weights through the CFG."))
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DISubprogram * getSubprogram() const
Get the attached subprogram.
static void clear(coro::Shape &Shape)
iterator insert(iterator I, T &&Elt)
static cl::opt< double > SampleProfileHotThreshold("sample-profile-inline-hot-threshold", cl::init(0.1), cl::value_desc("N"), cl::desc("Inlined functions that account for more than N% of all samples ""collected in the parent function, will be inlined again."))
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Represents the relative location of an instruction.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Represents a single loop in the control flow graph.
static cl::opt< unsigned > SampleProfileSampleCoverage("sample-profile-check-sample-coverage", cl::init(0), cl::value_desc("N"), cl::desc("Emit a warning if less than N% of samples in the input profile ""are matched to the IR."))
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
sample Sample Profile false
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
INITIALIZE_PASS_BEGIN(SampleProfileLoaderLegacyPass,"sample-profile","Sample Profile loader", false, false) INITIALIZE_PASS_END(SampleProfileLoaderLegacyPass
Provides ErrorOr<T> smart pointer.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
sample Sample Profile loader
This class implements an extremely fast bulk output stream that can only output to a stream...
ErrorOr< uint64_t > findSamplesAt(uint32_t LineOffset, uint32_t Discriminator) const
Return the number of samples collected at the given location.
StringRef - Represent a constant reference to a string, i.e.
A container for analyses that lazily runs them and caches their results.
Diagnostic information for the sample profiler.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
const BasicBlock * getParent() const
This file provides the interface for the sampled PGO loader pass.