84 #include <system_error> 89 using namespace sampleprof;
91 #define DEBUG_TYPE "sample-profile" 107 "sample-profile-max-propagate-iterations",
cl::init(100),
108 cl::desc(
"Maximum number of iterations to go through when propagating " 109 "sample block/edge weights through the CFG."));
113 cl::desc(
"Emit a warning if less than N% of records in the input profile " 114 "are matched to the IR."));
118 cl::desc(
"Emit a warning if less than N% of samples in the input profile " 119 "are matched to the IR."));
123 cl::desc(
"Use this option to turn off/on warnings about function with " 124 "samples but without debug information to use those samples. "));
128 cl::desc(
"If the sample profile is accurate, we will mark all un-sampled " 129 "callsite and function as having 0 samples. Otherwise, treat " 130 "un-sampled callsites and functions conservatively as unknown. "));
136 using Edge = std::pair<const BasicBlock *, const BasicBlock *>;
141 class SampleCoverageTracker {
143 SampleCoverageTracker() =
default;
146 uint32_t Discriminator, uint64_t Samples);
147 unsigned computeCoverage(
unsigned Used,
unsigned Total)
const;
152 uint64_t getTotalUsedSamples()
const {
return TotalUsedSamples; }
157 SampleCoverage.clear();
158 TotalUsedSamples = 0;
162 using BodySampleCoverageMap = std::map<LineLocation, unsigned>;
163 using FunctionSamplesCoverageMap =
175 FunctionSamplesCoverageMap SampleCoverage;
188 uint64_t TotalUsedSamples = 0;
196 class SampleProfileLoader {
202 : GetAC(
std::move(GetAssumptionCache)),
203 GetTTI(
std::move(GetTargetTransformInfo)), Filename(Name),
204 RemappingFilename(RemapName), IsThinLTOPreLink(IsThinLTOPreLink) {}
206 bool doInitialization(
Module &M);
210 void dump() { Reader->dump(); }
219 std::vector<const FunctionSamples *>
220 findIndirectCallFunctionSamples(
const Instruction &
I, uint64_t &Sum)
const;
230 void findEquivalenceClasses(
Function &
F);
231 template <
bool IsPostDom>
236 uint64_t visitEdge(Edge
E,
unsigned *NumUnknownEdges, Edge *UnknownEdge);
238 bool propagateThroughEdges(
Function &
F,
bool UpdateBlockCount);
239 void computeDominanceAndLoopInfo(
Function &
F);
240 void clearFunctionData();
246 BlockWeightMap BlockWeights;
252 EdgeWeightMap EdgeWeights;
266 EquivalenceClassMap EquivalenceClass;
275 std::unique_ptr<DominatorTree> DT;
276 std::unique_ptr<PostDominatorTree> PDT;
277 std::unique_ptr<LoopInfo> LI;
279 std::function<AssumptionCache &(Function &)> GetAC;
280 std::function<TargetTransformInfo &(Function &)> GetTTI;
283 BlockEdgeMap Predecessors;
286 BlockEdgeMap Successors;
288 SampleCoverageTracker CoverageTracker;
291 std::unique_ptr<SampleProfileReader> Reader;
297 std::string Filename;
300 std::string RemappingFilename;
303 bool ProfileIsValid =
false;
309 bool IsThinLTOPreLink;
318 uint64_t TotalCollectedSamples = 0;
324 class SampleProfileLoaderLegacyPass :
public ModulePass {
330 bool IsThinLTOPreLink =
false)
334 return ACT->getAssumptionCache(
F);
337 return TTIWP->getTTI(
F);
343 void dump() { SampleLoader.dump(); }
345 bool doInitialization(
Module &M)
override {
346 return SampleLoader.doInitialization(M);
349 StringRef getPassName()
const override {
return "Sample profile pass"; }
350 bool runOnModule(
Module &M)
override;
359 SampleProfileLoader SampleLoader;
382 assert(PSI &&
"PSI is expected to be non null");
396 unsigned &Count = SampleCoverage[FS][Loc];
397 bool FirstTime = (++Count == 1);
399 TotalUsedSamples += Samples;
409 auto I = SampleCoverage.find(FS);
413 unsigned Count = (
I != SampleCoverage.end()) ?
I->second.size() : 0;
419 for (
const auto &J :
I.second) {
422 Count += countUsedRecords(CalleeSamples, PSI);
438 for (
const auto &J :
I.second) {
441 Count += countBodyRecords(CalleeSamples, PSI);
455 Total +=
I.second.getSamples();
459 for (
const auto &J :
I.second) {
462 Total += countBodySamples(CalleeSamples, PSI);
473 unsigned SampleCoverageTracker::computeCoverage(
unsigned Used,
474 unsigned Total)
const {
476 "number of used records cannot exceed the total number of records");
477 return Total > 0 ? Used * 100 / Total : 100;
481 void SampleProfileLoader::clearFunctionData() {
482 BlockWeights.clear();
484 VisitedBlocks.clear();
485 VisitedEdges.clear();
486 EquivalenceClass.clear();
490 Predecessors.clear();
492 CoverageTracker.clear();
500 void SampleProfileLoader::printEdgeWeight(
raw_ostream &OS, Edge
E) {
501 OS <<
"weight[" << E.first->getName() <<
"->" << E.second->getName()
502 <<
"]: " << EdgeWeights[
E] <<
"\n";
509 void SampleProfileLoader::printBlockEquivalence(
raw_ostream &OS,
511 const BasicBlock *Equiv = EquivalenceClass[BB];
512 OS <<
"equivalence[" << BB->
getName()
513 <<
"]: " << ((Equiv) ? EquivalenceClass[BB]->
getName() :
"NONE") <<
"\n";
520 void SampleProfileLoader::printBlockWeight(
raw_ostream &OS,
522 const auto &
I = BlockWeights.find(BB);
523 uint64_t
W = (
I == BlockWeights.end() ? 0 :
I->second);
524 OS <<
"weight[" << BB->
getName() <<
"]: " << W <<
"\n";
542 return std::error_code();
546 return std::error_code();
551 if (isa<BranchInst>(Inst) || isa<IntrinsicInst>(Inst) || isa<PHINode>(Inst))
552 return std::error_code();
558 if ((isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) &&
560 findCalleeFunctionSamples(Inst))
569 CoverageTracker.markSamplesUsed(FS, LineOffset, Discriminator, R.
get());
573 Remark <<
"Applied " <<
ore::NV(
"NumSamples", *R);
574 Remark <<
" samples from profile (offset: ";
575 Remark <<
ore::NV(
"LineOffset", LineOffset);
578 Remark <<
ore::NV(
"Discriminator", Discriminator);
586 <<
" (line offset: " << LineOffset <<
"." 603 bool HasWeight =
false;
620 bool SampleProfileLoader::computeBlockWeights(
Function &
F) {
621 bool Changed =
false;
623 for (
const auto &BB : F) {
626 BlockWeights[&BB] = Weight.
get();
627 VisitedBlocks.insert(&BB);
649 SampleProfileLoader::findCalleeFunctionSamples(
const Instruction &Inst)
const {
656 if (
const CallInst *CI = dyn_cast<CallInst>(&Inst))
672 std::vector<const FunctionSamples *>
673 SampleProfileLoader::findIndirectCallFunctionSamples(
676 std::vector<const FunctionSamples *> R;
692 for (
const auto &T_C :
T.get())
698 for (
const auto &NameFS : *M) {
699 Sum += NameFS.second.getEntrySamples();
700 R.push_back(&NameFS.second);
722 SampleProfileLoader::findFunctionSamples(
const Instruction &Inst)
const {
727 auto it = DILocation2SampleMap.try_emplace(DIL,
nullptr);
729 it.first->second = Samples->findFunctionSamples(DIL);
730 return it.first->second;
733 bool SampleProfileLoader::inlineCallInstruction(
Instruction *
I) {
734 assert(isa<CallInst>(I) || isa<InvokeInst>(I));
749 None,
nullptr,
nullptr);
752 <<
"incompatible inlining");
759 <<
"inlined hot callee '" <<
ore::NV(
"Callee", CalledFunction)
779 bool SampleProfileLoader::inlineHotFunctions(
782 bool Changed =
false;
784 bool LocalChanged =
false;
791 if ((isa<CallInst>(I) || isa<InvokeInst>(I)) &&
792 !isa<IntrinsicInst>(
I) && (FS = findCalleeFunctionSamples(I))) {
805 if (CalledFunction == &F)
808 if (PromotedInsns.
count(I))
811 for (
const auto *FS : findIndirectCallFunctionSamples(*I, Sum)) {
812 if (IsThinLTOPreLink) {
823 if (CalleeFunctionName == F.getName())
826 const char *Reason =
"Callee function not available";
829 !R->getValue()->isDeclaration() &&
830 R->getValue()->getSubprogram() &&
838 if ((isa<CallInst>(DI) || isa<InvokeInst>(DI)) &&
839 inlineCallInstruction(DI))
843 <<
"\nFailed to promote indirect call to " 844 << CalleeFunctionName <<
" because " << Reason <<
"\n");
847 }
else if (CalledFunction && CalledFunction->
getSubprogram() &&
849 if (inlineCallInstruction(I))
851 }
else if (IsThinLTOPreLink) {
852 findCalleeFunctionSamples(*I)->findInlinedFunctions(
888 template <
bool IsPostDom>
889 void SampleProfileLoader::findEquivalencesFor(
893 uint64_t Weight = BlockWeights[EC];
894 for (
const auto *BB2 : Descendants) {
895 bool IsDomParent = DomTree->
dominates(BB2, BB1);
896 bool IsInSameLoop = LI->getLoopFor(BB1) == LI->getLoopFor(BB2);
897 if (BB1 != BB2 && IsDomParent && IsInSameLoop) {
898 EquivalenceClass[BB2] = EC;
900 if (VisitedBlocks.count(BB2)) {
901 VisitedBlocks.insert(EC);
912 Weight =
std::max(Weight, BlockWeights[BB2]);
916 BlockWeights[EC] = Samples->getHeadSamples() + 1;
918 BlockWeights[EC] = Weight;
931 void SampleProfileLoader::findEquivalenceClasses(
Function &F) {
939 if (EquivalenceClass.count(BB1)) {
945 EquivalenceClass[BB1] = BB1;
957 DominatedBBs.
clear();
958 DT->getDescendants(BB1, DominatedBBs);
959 findEquivalencesFor(BB1, DominatedBBs, PDT.get());
971 dbgs() <<
"\nAssign the same weight to all blocks in the same class\n");
974 const BasicBlock *EquivBB = EquivalenceClass[BB];
976 BlockWeights[BB] = BlockWeights[EquivBB];
991 uint64_t SampleProfileLoader::visitEdge(Edge E,
unsigned *NumUnknownEdges,
993 if (!VisitedEdges.count(E)) {
994 (*NumUnknownEdges)++;
999 return EdgeWeights[
E];
1015 bool SampleProfileLoader::propagateThroughEdges(
Function &F,
1016 bool UpdateBlockCount) {
1017 bool Changed =
false;
1019 for (
const auto &BI : F) {
1028 for (
unsigned i = 0; i < 2; i++) {
1029 uint64_t TotalWeight = 0;
1030 unsigned NumUnknownEdges = 0, NumTotalEdges = 0;
1031 Edge UnknownEdge, SelfReferentialEdge, SingleEdge;
1035 NumTotalEdges = Predecessors[BB].size();
1036 for (
auto *Pred : Predecessors[BB]) {
1037 Edge E = std::make_pair(Pred, BB);
1038 TotalWeight += visitEdge(E, &NumUnknownEdges, &UnknownEdge);
1039 if (E.first == E.second)
1040 SelfReferentialEdge =
E;
1042 if (NumTotalEdges == 1) {
1043 SingleEdge = std::make_pair(Predecessors[BB][0], BB);
1047 NumTotalEdges = Successors[BB].size();
1048 for (
auto *Succ : Successors[BB]) {
1049 Edge E = std::make_pair(BB, Succ);
1050 TotalWeight += visitEdge(E, &NumUnknownEdges, &UnknownEdge);
1052 if (NumTotalEdges == 1) {
1053 SingleEdge = std::make_pair(BB, Successors[BB][0]);
1080 if (NumUnknownEdges <= 1) {
1081 uint64_t &BBWeight = BlockWeights[EC];
1082 if (NumUnknownEdges == 0) {
1083 if (!VisitedBlocks.count(EC)) {
1087 if (TotalWeight > BBWeight) {
1088 BBWeight = TotalWeight;
1091 <<
" known. Set weight for block: ";
1092 printBlockWeight(
dbgs(), BB););
1094 }
else if (NumTotalEdges == 1 &&
1095 EdgeWeights[SingleEdge] < BlockWeights[EC]) {
1098 EdgeWeights[SingleEdge] = BlockWeights[EC];
1101 }
else if (NumUnknownEdges == 1 && VisitedBlocks.count(EC)) {
1104 if (BBWeight >= TotalWeight)
1105 EdgeWeights[UnknownEdge] = BBWeight - TotalWeight;
1107 EdgeWeights[UnknownEdge] = 0;
1110 OtherEC = EquivalenceClass[UnknownEdge.first];
1112 OtherEC = EquivalenceClass[UnknownEdge.second];
1114 if (VisitedBlocks.count(OtherEC) &&
1115 EdgeWeights[UnknownEdge] > BlockWeights[OtherEC])
1116 EdgeWeights[UnknownEdge] = BlockWeights[OtherEC];
1117 VisitedEdges.insert(UnknownEdge);
1120 printEdgeWeight(
dbgs(), UnknownEdge));
1122 }
else if (VisitedBlocks.count(EC) && BlockWeights[EC] == 0) {
1125 for (
auto *Pred : Predecessors[BB]) {
1126 Edge E = std::make_pair(Pred, BB);
1128 VisitedEdges.insert(E);
1131 for (
auto *Succ : Successors[BB]) {
1132 Edge E = std::make_pair(BB, Succ);
1134 VisitedEdges.insert(E);
1137 }
else if (SelfReferentialEdge.first && VisitedBlocks.count(EC)) {
1138 uint64_t &BBWeight = BlockWeights[BB];
1140 if (BBWeight >= TotalWeight)
1141 EdgeWeights[SelfReferentialEdge] = BBWeight - TotalWeight;
1143 EdgeWeights[SelfReferentialEdge] = 0;
1144 VisitedEdges.insert(SelfReferentialEdge);
1147 printEdgeWeight(
dbgs(), SelfReferentialEdge));
1149 if (UpdateBlockCount && !VisitedBlocks.count(EC) && TotalWeight > 0) {
1150 BlockWeights[EC] = TotalWeight;
1151 VisitedBlocks.insert(EC);
1164 void SampleProfileLoader::buildEdges(
Function &F) {
1165 for (
auto &BI : F) {
1170 if (!Predecessors[B1].
empty())
1174 if (Visited.
insert(B2).second)
1175 Predecessors[B1].push_back(B2);
1180 if (!Successors[B1].
empty())
1184 if (Visited.
insert(B2).second)
1185 Successors[B1].push_back(B2);
1194 for (
auto I = M.
begin(); I != M.
end(); ++
I)
1195 R.
push_back({FunctionSamples::getGUID(I->getKey()), I->getValue()});
1196 llvm::sort(R, [](
const InstrProfValueData &L,
const InstrProfValueData &R) {
1197 if (L.Count == R.Count)
1198 return L.Value > R.Value;
1200 return L.Count > R.Count;
1222 void SampleProfileLoader::propagateWeights(
Function &F) {
1223 bool Changed =
true;
1228 for (
auto &BI : F) {
1230 Loop *L = LI->getLoopFor(BB);
1235 if (Header && BlockWeights[BB] > BlockWeights[Header]) {
1236 BlockWeights[Header] = BlockWeights[BB];
1249 Changed = propagateThroughEdges(F,
false);
1255 VisitedEdges.clear();
1258 Changed = propagateThroughEdges(F,
false);
1265 Changed = propagateThroughEdges(F,
true);
1270 LLVM_DEBUG(
dbgs() <<
"\nPropagation complete. Setting branch weights\n");
1273 for (
auto &BI : F) {
1276 if (BlockWeights[BB]) {
1277 for (
auto &I : BB->getInstList()) {
1278 if (!isa<CallInst>(I) && !isa<InvokeInst>(
I))
1282 const DebugLoc &DLoc = I.getDebugLoc();
1293 if (!
T ||
T.get().empty())
1298 findIndirectCallFunctionSamples(I, Sum);
1300 SortedCallTargets, Sum, IPVK_IndirectCallTarget,
1301 SortedCallTargets.
size());
1302 }
else if (!dyn_cast<IntrinsicInst>(&I)) {
1312 if (!isa<BranchInst>(TI) && !isa<SwitchInst>(TI))
1318 :
Twine(
"<UNKNOWN LOCATION>"))
1325 Edge E = std::make_pair(BB, Succ);
1326 uint64_t Weight = EdgeWeights[
E];
1337 Weights.
push_back(static_cast<uint32_t>(Weight + 1));
1339 if (Weight > MaxWeight) {
1346 uint64_t TempWeight;
1358 <<
"most popular destination for conditional branches at " 1359 <<
ore::NV(
"CondBranchesLoc", BranchLoc);
1378 unsigned SampleProfileLoader::getFunctionLoc(
Function &F) {
1380 return S->getLine();
1388 "No debug information found in function " + F.
getName() +
1389 ": Function profile not used",
1394 void SampleProfileLoader::computeDominanceAndLoopInfo(
Function &F) {
1453 bool SampleProfileLoader::emitAnnotations(
Function &F) {
1454 bool Changed =
false;
1456 if (getFunctionLoc(F) == 0)
1460 << F.
getName() <<
": " << getFunctionLoc(F) <<
"\n");
1463 Changed |= inlineHotFunctions(F, InlinedGUIDs);
1466 Changed |= computeBlockWeights(F);
1479 computeDominanceAndLoopInfo(F);
1482 findEquivalenceClasses(F);
1485 propagateWeights(F);
1490 unsigned Used = CoverageTracker.countUsedRecords(Samples, PSI);
1491 unsigned Total = CoverageTracker.countBodyRecords(Samples, PSI);
1492 unsigned Coverage = CoverageTracker.computeCoverage(Used, Total);
1496 Twine(Used) +
" of " +
Twine(Total) +
" available profile records (" +
1497 Twine(Coverage) +
"%) were applied",
1503 uint64_t Used = CoverageTracker.getTotalUsedSamples();
1504 uint64_t Total = CoverageTracker.countBodySamples(Samples, PSI);
1505 unsigned Coverage = CoverageTracker.computeCoverage(Used, Total);
1509 Twine(Used) +
" of " +
Twine(Total) +
" available profile samples (" +
1510 Twine(Coverage) +
"%) were applied",
1520 "Sample Profile loader",
false,
false)
1527 bool SampleProfileLoader::doInitialization(
Module &M) {
1528 auto &Ctx = M.getContext();
1530 if (std::error_code EC = ReaderOrErr.getError()) {
1531 std::string Msg =
"Could not open profile: " + EC.message();
1535 Reader = std::move(ReaderOrErr.get());
1536 Reader->collectFuncsToUse(M);
1539 if (!RemappingFilename.empty()) {
1544 RemappingFilename, Ctx, std::move(Reader));
1545 if (std::error_code EC = ReaderOrErr.getError()) {
1546 std::string Msg =
"Could not open profile remapping file: " + EC.message();
1550 Reader = std::move(ReaderOrErr.get());
1557 return new SampleProfileLoaderLegacyPass();
1561 return new SampleProfileLoaderLegacyPass(Name);
1567 if (!ProfileIsValid)
1575 for (
const auto &
I : Reader->getProfiles())
1576 TotalCollectedSamples +=
I.second.getTotalSamples();
1585 auto pos = OrigName.
find(
'.');
1594 r.first->second =
nullptr;
1598 bool retval =
false;
1600 if (!
F.isDeclaration()) {
1601 clearFunctionData();
1607 bool SampleProfileLoaderLegacyPass::runOnModule(
Module &M) {
1608 ACT = &getAnalysis<AssumptionCacheTracker>();
1609 TTIWP = &getAnalysis<TargetTransformInfoWrapperPass>();
1611 &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
1612 return SampleLoader.runOnModule(M,
nullptr, PSI);
1617 DILocation2SampleMap.clear();
1625 uint64_t initialEntryCount =
1630 std::unique_ptr<OptimizationRemarkEmitter> OwnedORE;
1637 OwnedORE = make_unique<OptimizationRemarkEmitter>(&
F);
1638 ORE = OwnedORE.get();
1640 Samples = Reader->getSamplesFor(F);
1641 if (Samples && !Samples->empty())
1642 return emitAnnotations(F);
1658 SampleProfileLoader SampleLoader(
1661 : ProfileRemappingFileName,
1662 IsThinLTOPreLink, GetAssumptionCache, GetTTI);
1664 SampleLoader.doInitialization(M);
1667 if (!SampleLoader.runOnModule(M, &AM, PSI))
const FunctionSamplesMap * findFunctionSamplesMapAt(const LineLocation &Loc) const
Returns the FunctionSamplesMap at the given Loc.
static uint64_t getGUID(StringRef Name)
Thresholds to tune inline cost analysis.
Represents either an error or a value T.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
DiagnosticInfoOptimizationBase::Argument NV
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
A Module instance is used to store all the information related to an LLVM module. ...
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
Implements a dense probed hash-table based set.
void push_back(const T &Elt)
const ValueSymbolTable & getValueSymbolTable() const
Get the symbol table of global variable and function identifiers.
Analysis providing profile information.
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 @llvm.assume calls within a function.
Analysis pass providing the TargetTransformInfo.
bool isLegalToPromote(CallSite CS, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
static ErrorOr< std::unique_ptr< SampleProfileReader > > create(const Twine &Filename, LLVMContext &C)
Create a sample profile reader appropriate to the file format.
ErrorOr< uint64_t > findSamplesAt(uint32_t LineOffset, uint32_t Discriminator) const
Return the number of samples collected at the given location.
uint64_t getOrCompHotCountThreshold()
Returns HotCountThreshold if set.
InlineResult InlineFunction(CallInst *C, InlineFunctionInfo &IFI, AAResults *CalleeAAR=nullptr, bool InsertLifetime=true)
This function inlines the called function into the basic block of the caller.
void findInlinedFunctions(DenseSet< GlobalValue::GUID > &S, const Module *M, uint64_t Threshold) const
Recursively traverses all children, if the total sample count of the corresponding function is no les...
static SmallVector< InstrProfValueData, 2 > SortCallTargets(const SampleRecord::CallTargetMap &M)
Returns the sorted CallTargetMap M by count in descending order.
This class captures the data input to the InlineFunction call, and records the auxiliary results prod...
bool isHotCount(uint64_t C)
Returns true if count C is considered hot.
Represents the cost of inlining a function.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Representation of the samples collected for a function.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
void setEntryCount(ProfileCount Count, const DenseSet< GlobalValue::GUID > *Imports=nullptr)
Set the entry count for this function.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
static cl::opt< std::string > SampleProfileRemappingFile("sample-profile-remapping-file", cl::init(""), cl::value_desc("filename"), cl::desc("Profile remapping file loaded by -sample-profile"), cl::Hidden)
LLVMContext & getContext() const
Get the global data context.
static StringRef getName(Value *V)
Metadata * getProfileSummary()
Returns profile summary metadata.
StringRef getFilename() const
BlockT * getHeader() 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...
const Instruction * getFirstNonPHIOrDbgOrLifetime() const
Returns a pointer to the first instruction in this block that is not a PHINode, a debug intrinsic...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
bool extractProfTotalWeight(uint64_t &TotalVal) const
Retrieve total raw weight values of a branch.
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)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
ModulePass * createSampleProfileLoaderPass()
Instruction * promoteIndirectCall(Instruction *Inst, Function *F, uint64_t Count, uint64_t TotalCount, bool AttachProfToDirectCall, OptimizationRemarkEmitter *ORE)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
amdgpu Simplify well known AMD library false Value * Callee
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
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."))
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Interval::succ_iterator succ_end(Interval *I)
iterator find(const_arg_type_t< KeyT > Val)
Core dominator tree base class.
const BasicBlock & getEntryBlock() const
static bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
A set of analyses that are preserved following a run of a transformation pass.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
LLVM Basic Block Representation.
This is an important class for using LLVM in a threaded context.
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."))
DISubprogram * getSubprogram() const
Get the attached subprogram.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
const BodySampleMap & getBodySamples() const
Return all the samples collected in the body of the function.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< iterator, bool > insert(const ValueT &V)
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...
Function::ProfileCount ProfileCount
Represent the analysis usage information of a pass.
Interval::pred_iterator pred_end(Interval *I)
DenseMap< SymbolStringPtr, JITEvaluatedSymbol > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
void initializeSampleProfileLoaderLegacyPassPass(PassRegistry &)
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Used in the streaming interface as the general argument type.
void annotateValueSite(Module &M, Instruction &Inst, const InstrProfRecord &InstrProfR, InstrProfValueKind ValueKind, uint32_t SiteIndx, uint32_t MaxMDCount=3)
Get the value profile data for value site SiteIdx from InstrProfR and annotate the instruction Inst w...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Class to represent profile counts.
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight)
Return metadata containing two branch weights.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#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.
StringRef getFuncNameInModule(const Module *M) const
Return the original function name if it exists in Module M.
InlineCost getInlineCost(CallSite CS, const InlineParams &Params, TargetTransformInfo &CalleeTTI, std::function< AssumptionCache &(Function &)> &GetAssumptionCache, Optional< function_ref< BlockFrequencyInfo &(Function &)>> GetBFI, ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE=nullptr)
Get an InlineCost object representing the cost of inlining this callsite.
Optional< bool > ComputeFullInlineCost
Compute inline cost even when the cost has exceeded the threshold.
void sort(IteratorTy Start, IteratorTy End)
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
const FunctionSamples * findFunctionSamplesAt(const LineLocation &Loc, StringRef CalleeName) const
Returns a pointer to FunctionSamples at the given callsite location Loc with callee CalleeName...
A function analysis which provides an AssumptionCache.
const InstListType & getInstList() const
Return the underlying instruction list container.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
InlineParams getInlineParams()
Generate the parameters to tune the inline cost analysis based only on the commandline options...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
static unsigned getOffset(const DILocation *DIL)
Returns the line offset to the start line of the subprogram.
static cl::opt< bool > ProfileSampleAccurate("profile-sample-accurate", cl::Hidden, cl::init(false), cl::desc("If the sample profile is accurate, we will mark all un-sampled " "callsite and function as having 0 samples. Otherwise, treat " "un-sampled callsites and functions conservatively as unknown. "))
ErrorOr< SampleRecord::CallTargetMap > findCallTargetMapAt(uint32_t LineOffset, uint32_t Discriminator) const
Returns the call target map collected at a given location.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
static void clear(coro::Shape &Shape)
iterator insert(iterator I, T &&Elt)
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void setProfileSummary(Metadata *M)
Attach profile summary metadata to this module.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
unsigned getBaseDiscriminator() const
Returns the base discriminator stored in the discriminator.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Represents the relative location of an instruction.
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."))
static bool callsiteIsHot(const FunctionSamples *CallsiteFS, ProfileSummaryInfo *PSI)
Return true if the given callsite is hot wrt to hot cutoff threshold.
Represents a single loop in the control flow graph.
StringRef getName() const
Return a constant reference to the value's name.
Establish a view to a call site for examination.
const Function * getParent() const
Return the enclosing method, or null if none.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
std::map< std::string, FunctionSamples > FunctionSamplesMap
StringRef getName() const
Return the function name.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
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
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Provides ErrorOr<T> smart pointer.
FunTy * getCalledFunction() const
Return the function being called if this is a direct call, otherwise return null (if it's an indirect...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
sample Sample Profile loader
const CallsiteSampleMap & getCallsiteSamples() const
Return all the callsite samples collected in the body of the function.
This class implements an extremely fast bulk output stream that can only output to a stream...
print Print MemDeps of function
This file defines a set of templates that efficiently compute a dominator tree over a generic graph...
StringRef - Represent a constant reference to a string, i.e.
A container for analyses that lazily runs them and caches their results.
uint64_t getEntrySamples() const
Return the sample count of the first instruction of the function.
static cl::opt< bool > NoWarnSampleUnused("no-warn-sample-unused", cl::init(false), cl::Hidden, cl::desc("Use this option to turn off/on warnings about function with " "samples but without debug information to use those samples. "))
This header defines various interfaces for pass management in LLVM.
Diagnostic information for the sample profiler.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
This file provides the interface for the sampled PGO loader pass.
const BasicBlock * getParent() const
static ErrorOr< std::unique_ptr< SampleProfileReader > > create(const Twine &Filename, LLVMContext &C, std::unique_ptr< SampleProfileReader > Underlying)
Create a remapped sample profile from the given remapping file and underlying samples.
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...