126#include <unordered_map>
134#define DEBUG_TYPE "pgo-instrumentation"
136STATISTIC(NumOfPGOInstrument,
"Number of edges instrumented.");
137STATISTIC(NumOfPGOSelectInsts,
"Number of select instruction instrumented.");
138STATISTIC(NumOfPGOMemIntrinsics,
"Number of mem intrinsics instrumented.");
141STATISTIC(NumOfPGOSplit,
"Number of critical edge splits.");
142STATISTIC(NumOfPGOFunc,
"Number of functions having valid profile counts.");
143STATISTIC(NumOfPGOMismatch,
"Number of functions having mismatch profile.");
144STATISTIC(NumOfPGOMissing,
"Number of functions without profile.");
145STATISTIC(NumOfPGOICall,
"Number of indirect call value instrumentations.");
146STATISTIC(NumOfCSPGOInstrument,
"Number of edges instrumented in CSPGO.");
148 "Number of select instruction instrumented in CSPGO.");
150 "Number of mem intrinsics instrumented in CSPGO.");
152STATISTIC(NumOfCSPGOBB,
"Number of basic-blocks in CSPGO.");
153STATISTIC(NumOfCSPGOSplit,
"Number of critical edge splits in CSPGO.");
155 "Number of functions having valid profile counts in CSPGO.");
157 "Number of functions having mismatch profile in CSPGO.");
158STATISTIC(NumOfCSPGOMissing,
"Number of functions without profile in CSPGO.");
159STATISTIC(NumCoveredBlocks,
"Number of basic blocks that were executed");
166 cl::desc(
"Specify the path of profile data file. This is "
167 "mainly for test purpose."));
171 cl::desc(
"Specify the path of profile remapping file. This is mainly for "
178 cl::desc(
"Disable Value Profiling"));
184 cl::desc(
"Max number of annotations for a single indirect "
191 cl::desc(
"Max number of precise value annotations for a single memop"
198 cl::desc(
"Append function hash to the name of COMDAT function to avoid "
199 "function hash mismatch due to the preinliner"));
206 cl::desc(
"Use this option to turn on/off "
207 "warnings about missing profile data for "
214 cl::desc(
"Use this option to turn off/on "
215 "warnings about profile cfg mismatch."));
222 cl::desc(
"The option is used to turn on/off "
223 "warnings about hash mismatch for comdat "
224 "or weak functions."));
229 cl::desc(
"Use this option to turn on/off SELECT "
230 "instruction instrumentation. "));
235 cl::desc(
"A boolean option to show CFG dag or text "
236 "with raw profile counts from "
237 "profile data. See also option "
238 "-pgo-view-counts. To limit graph "
239 "display to only one function, use "
240 "filtering option -view-bfi-func-name."),
248 cl::desc(
"Use this option to turn on/off "
249 "memory intrinsic size profiling."));
254 cl::desc(
"When this option is on, the annotated "
255 "branch probability will be emitted as "
256 "optimization remarks: -{Rpass|"
257 "pass-remarks}=pgo-instrumentation"));
261 cl::desc(
"Force to instrument function entry basicblock."));
266 cl::desc(
"Force to instrument loop entries."));
271 "Use this option to enable function entry coverage instrumentation."));
274 "pgo-block-coverage",
275 cl::desc(
"Use this option to enable basic block coverage instrumentation"));
279 cl::desc(
"Create a dot file of CFGs with block "
280 "coverage inference information"));
283 "pgo-temporal-instrumentation",
284 cl::desc(
"Use this option to enable temporal instrumentation"));
288 cl::desc(
"Fix function entry count in profile use."));
292 cl::desc(
"Print out the non-match BFI count if a hot raw profile count "
293 "becomes non-hot, or a cold raw profile count becomes hot. "
294 "The print is enabled under -Rpass-analysis=pgo, or "
295 "internal option -pass-remarks-analysis=pgo."));
299 cl::desc(
"Print out mismatched BFI counts after setting profile metadata "
300 "The print is enabled under -Rpass-analysis=pgo, or "
301 "internal option -pass-remarks-analysis=pgo."));
305 cl::desc(
"Set the threshold for pgo-verify-bfi: only print out "
306 "mismatched BFI if the difference percentage is greater than "
307 "this value (in percentage)."));
311 cl::desc(
"Set the threshold for pgo-verify-bfi: skip the counts whose "
312 "profile count value is below."));
317 cl::desc(
"Trace the hash of the function with this name."));
321 cl::desc(
"Do not instrument functions smaller than this threshold."));
325 cl::desc(
"Do not instrument functions with the number of critical edges "
326 " greater than this threshold."));
330 cl::desc(
"For cold function instrumentation, skip instrumenting functions "
331 "whose entry count is above the given value."));
335 cl::desc(
"For cold function instrumentation, treat count unknown(e.g. "
336 "unprofiled) functions as cold."));
340 cl::desc(
"Enable cold function only instrumentation."));
344 cl::desc(
"Do not instrument callsites to functions in this list. Intended "
366class FunctionInstrumenter final {
370 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
381 bool isValueProfilingDisabled()
const {
386 bool shouldInstrumentEntryBB()
const {
394 FunctionInstrumenter(
396 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
400 : M(M),
F(
F), TLI(TLI), ComdatMembers(ComdatMembers), BPI(BPI), BFI(BFI),
401 LI(LI), InstrumentationType(InstrumentationType) {}
412 return std::string();
417 return std::string();
429 else if (CV->
isOne())
440#define VALUE_PROF_KIND(Enumerator, Value, Descr) Descr,
473 IRLevelVersionVariable->setVisibility(
476 Triple TT(M.getTargetTriple());
477 if (TT.supportsCOMDAT()) {
479 IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName));
481 return IRLevelVersionVariable;
491enum VisitMode { VM_counting, VM_instrument, VM_annotate };
495struct SelectInstVisitor :
public InstVisitor<SelectInstVisitor> {
498 VisitMode Mode = VM_counting;
499 unsigned *CurCtrIdx =
nullptr;
500 unsigned TotalNumCtrs = 0;
501 GlobalValue *FuncNameVar =
nullptr;
502 uint64_t FuncHash = 0;
503 PGOUseFunc *UseFunc =
nullptr;
504 bool HasSingleByteCoverage;
506 SelectInstVisitor(Function &Func,
bool HasSingleByteCoverage)
507 : F(
Func), HasSingleByteCoverage(HasSingleByteCoverage) {}
509 void countSelects() {
519 void instrumentSelects(
unsigned *Ind,
unsigned TotalNC, GlobalValue *FNV,
521 Mode = VM_instrument;
523 TotalNumCtrs = TotalNC;
530 void annotateSelects(PGOUseFunc *UF,
unsigned *Ind) {
537 void instrumentOneSelectInst(SelectInst &SI);
538 void annotateOneSelectInst(SelectInst &SI);
541 void visitSelectInst(SelectInst &SI);
545 unsigned getNumOfSelectInsts()
const {
return NSIs; }
557 bool Removed =
false;
558 bool IsCritical =
false;
560 PGOEdge(BasicBlock *Src, BasicBlock *Dest, uint64_t W = 1)
561 : SrcBB(Src), DestBB(Dest), Weight(
W) {}
564 std::string infoString()
const {
565 return (Twine(Removed ?
"-" :
" ") + (InMST ?
" " :
"*") +
566 (IsCritical ?
"c" :
" ") +
" W=" + Twine(Weight))
577 PGOBBInfo(
unsigned IX) : Group(this), Index(IX) {}
580 std::string infoString()
const {
581 return (Twine(
"Index=") + Twine(Index)).str();
586template <
class Edge,
class BBInfo>
class FuncPGOInstrumentation {
594 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
596 ValueProfileCollector VPC;
598 void computeCFGHash();
599 void renameComdatFunction();
602 const TargetLibraryInfo &TLI;
603 std::vector<std::vector<VPCandidateInfo>> ValueSites;
604 SelectInstVisitor SIVisitor;
605 std::string FuncName;
606 std::string DeprecatedFuncName;
607 GlobalVariable *FuncNameVar;
610 uint64_t FunctionHash = 0;
613 CFGMST<Edge, BBInfo> MST;
615 const std::optional<BlockCoverageInference> BCI;
617 static std::optional<BlockCoverageInference>
618 constructBCI(Function &Func,
bool HasSingleByteCoverage,
619 bool InstrumentFuncEntry) {
620 if (HasSingleByteCoverage)
621 return BlockCoverageInference(Func, InstrumentFuncEntry);
627 void getInstrumentBBs(std::vector<BasicBlock *> &InstrumentBBs);
634 BBInfo &getBBInfo(
const BasicBlock *BB)
const {
return MST.getBBInfo(BB); }
637 BBInfo *findBBInfo(
const BasicBlock *BB)
const {
return MST.findBBInfo(BB); }
640 void dumpInfo(StringRef Str =
"")
const {
641 MST.dumpEdges(
dbgs(), Twine(
"Dump Function ") + FuncName +
642 " Hash: " + Twine(FunctionHash) +
"\t" + Str);
645 FuncPGOInstrumentation(
646 Function &Func, TargetLibraryInfo &TLI,
647 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
648 bool CreateGlobalVar =
false, BranchProbabilityInfo *BPI =
nullptr,
649 BlockFrequencyInfo *BFI =
nullptr, LoopInfo *LI =
nullptr,
650 bool IsCS =
false,
bool InstrumentFuncEntry =
true,
651 bool InstrumentLoopEntries =
false,
bool HasSingleByteCoverage =
false)
652 : F(
Func), IsCS(IsCS), ComdatMembers(ComdatMembers), VPC(
Func, TLI),
653 TLI(TLI), ValueSites(IPVK_Last + 1),
654 SIVisitor(
Func, HasSingleByteCoverage),
655 MST(F, InstrumentFuncEntry, InstrumentLoopEntries, BPI,
BFI, LI),
656 BCI(constructBCI(
Func, HasSingleByteCoverage, InstrumentFuncEntry)) {
658 BCI->viewBlockCoverageGraph();
660 SIVisitor.countSelects();
661 ValueSites[IPVK_MemOPSize] = VPC.get(IPVK_MemOPSize);
663 NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
664 NumOfPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
665 NumOfPGOBB += MST.bbInfoSize();
666 ValueSites[IPVK_IndirectCallTarget] = VPC.get(IPVK_IndirectCallTarget);
668 ValueSites[IPVK_VTableTarget] = VPC.get(IPVK_VTableTarget);
670 NumOfCSPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
671 NumOfCSPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
672 NumOfCSPGOBB += MST.bbInfoSize();
678 if (!ComdatMembers.empty())
679 renameComdatFunction();
682 for (
const auto &
E : MST.allEdges()) {
685 IsCS ? NumOfCSPGOEdge++ : NumOfPGOEdge++;
687 IsCS ? NumOfCSPGOInstrument++ : NumOfPGOInstrument++;
700template <
class Edge,
class BBInfo>
701void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
702 std::vector<uint8_t> Indexes;
706 auto BI = findBBInfo(Succ);
710 for (
int J = 0; J < 4; J++)
711 Indexes.push_back((
uint8_t)(Index >> (J * 8)));
718 auto updateJCH = [&JCH](
uint64_t Num) {
723 updateJCH((
uint64_t)SIVisitor.getNumOfSelectInsts());
724 updateJCH((
uint64_t)ValueSites[IPVK_IndirectCallTarget].
size());
727 updateJCH(BCI->getInstrumentedBlocksHash());
737 FunctionHash &= 0x0FFFFFFFFFFFFFFF;
740 LLVM_DEBUG(
dbgs() <<
"Function Hash Computation for " <<
F.getName() <<
":\n"
741 <<
" CRC = " << JC.
getCRC()
742 <<
", Selects = " << SIVisitor.getNumOfSelectInsts()
743 <<
", Edges = " << MST.
numEdges() <<
", ICSites = "
744 << ValueSites[IPVK_IndirectCallTarget].size()
745 <<
", Memops = " << ValueSites[IPVK_MemOPSize].size()
746 <<
", High32 CRC = " << JCH.
getCRC()
747 <<
", Hash = " << FunctionHash <<
"\n";);
750 dbgs() <<
"Funcname=" <<
F.getName() <<
", Hash=" << FunctionHash
751 <<
" in building " <<
F.getParent()->getSourceFileName() <<
"\n";
757 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
769 for (
auto &&CM :
make_range(ComdatMembers.equal_range(
C))) {
779template <
class Edge,
class BBInfo>
780void FuncPGOInstrumentation<Edge, BBInfo>::renameComdatFunction() {
783 std::string OrigName =
F.getName().str();
784 std::string NewFuncName =
786 F.setName(
Twine(NewFuncName));
788 FuncName =
Twine(FuncName +
"." +
Twine(FunctionHash)).
str();
794 if (!
F.hasComdat()) {
796 NewComdat = M->getOrInsertComdat(
StringRef(NewFuncName));
798 F.setComdat(NewComdat);
803 Comdat *OrigComdat =
F.getComdat();
804 std::string NewComdatName =
806 NewComdat = M->getOrInsertComdat(
StringRef(NewComdatName));
809 for (
auto &&CM :
make_range(ComdatMembers.equal_range(OrigComdat))) {
817template <
class Edge,
class BBInfo>
818void FuncPGOInstrumentation<Edge, BBInfo>::getInstrumentBBs(
819 std::vector<BasicBlock *> &InstrumentBBs) {
822 if (BCI->shouldInstrumentBlock(BB))
823 InstrumentBBs.push_back(&BB);
828 std::vector<Edge *> EdgeList;
831 EdgeList.push_back(
E.get());
833 for (
auto &
E : EdgeList) {
836 InstrumentBBs.push_back(InstrBB);
842template <
class Edge,
class BBInfo>
843BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *
E) {
844 if (
E->InMST ||
E->Removed)
850 if (SrcBB ==
nullptr)
852 if (DestBB ==
nullptr)
867 return canInstrument(SrcBB);
869 return canInstrument(DestBB);
878 dbgs() <<
"Fail to split critical edge: not instrument this edge.\n");
883 IsCS ? NumOfCSPGOSplit++ : NumOfPGOSplit++;
884 LLVM_DEBUG(
dbgs() <<
"Split critical edge: " << getBBInfo(SrcBB).Index
885 <<
" --> " << getBBInfo(DestBB).Index <<
"\n");
887 MST.
addEdge(SrcBB, InstrBB, 0);
889 Edge &NewEdge1 = MST.
addEdge(InstrBB, DestBB, 0);
890 NewEdge1.InMST =
true;
893 return canInstrument(InstrBB);
912 std::optional<OperandBundleUse> ParentFunclet =
920 if (!BlockColors.
empty()) {
921 const ColorVector &CV = BlockColors.
find(OrigCall->getParent())->second;
922 assert(CV.
size() == 1 &&
"non-unique color for block!");
924 if (EHPadIt->isEHPad())
932void FunctionInstrumenter::instrument() {
939 const bool IsCtxProf = InstrumentationType == PGOInstrumentationType::CTXPROF;
940 FuncPGOInstrumentation<PGOEdge, PGOBBInfo> FuncInfo(
941 F, TLI, ComdatMembers, !IsCtxProf, BPI, BFI, LI,
942 InstrumentationType == PGOInstrumentationType::CSFDO,
943 shouldInstrumentEntryBB(), shouldInstrumentLoopEntries(),
947 auto *
const CFGHash =
948 ConstantInt::get(Type::getInt64Ty(
M.getContext()), FuncInfo.FunctionHash);
952 Name, PointerType::get(
M.getContext(), 0));
954 auto &EntryBB =
F.getEntryBlock();
955 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstNonPHIOrDbgOrAlloca());
958 Builder.CreateIntrinsic(
959 Intrinsic::instrprof_cover,
960 {NormalizedNamePtr, CFGHash, Builder.getInt32(1), Builder.getInt32(0)});
964 std::vector<BasicBlock *> InstrumentBBs;
965 FuncInfo.getInstrumentBBs(InstrumentBBs);
967 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
982 auto Visit = [&](llvm::function_ref<void(CallBase * CB)> Visitor) {
984 for (
auto &Instr : BB)
988 if (CS->getCalledFunction() &&
989 SkipCSInstr.contains(CS->getCalledFunction()->getName()))
995 uint32_t TotalNumCallsites = 0;
996 Visit([&TotalNumCallsites](
auto *) { ++TotalNumCallsites; });
1000 Visit([&](
auto *CB) {
1002 Builder.CreateCall(CSIntrinsic,
1003 {
Name, CFGHash, Builder.getInt32(TotalNumCallsites),
1005 CB->getCalledOperand()});
1012 auto &EntryBB =
F.getEntryBlock();
1013 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstNonPHIOrDbgOrAlloca());
1016 Builder.CreateIntrinsic(Intrinsic::instrprof_timestamp,
1017 {NormalizedNamePtr, CFGHash,
1019 Builder.getInt32(
I)});
1023 for (
auto *InstrBB : InstrumentBBs) {
1025 assert(Builder.GetInsertPoint() != InstrBB->
end() &&
1026 "Cannot get the Instrumentation point");
1030 : Intrinsic::instrprof_increment,
1031 {NormalizedNamePtr, CFGHash,
1033 Builder.getInt32(
I++)});
1037 FuncInfo.SIVisitor.instrumentSelects(&
I,
NumCounters, Name,
1038 FuncInfo.FunctionHash);
1041 if (isValueProfilingDisabled())
1044 NumOfPGOICall += FuncInfo.ValueSites[IPVK_IndirectCallTarget].size();
1050 DenseMap<BasicBlock *, ColorVector> BlockColors;
1051 if (
F.hasPersonalityFn() &&
1056 for (uint32_t Kind = IPVK_First;
Kind <= IPVK_Last; ++
Kind) {
1057 unsigned SiteIndex = 0;
1063 <<
" site: CallSite Index = " << SiteIndex <<
"\n");
1066 assert(Builder.GetInsertPoint() != Cand.InsertPt->getParent()->end() &&
1067 "Cannot get the Instrumentation point");
1069 Value *ToProfile =
nullptr;
1070 if (Cand.V->getType()->isIntegerTy())
1071 ToProfile = Builder.CreateZExtOrTrunc(Cand.V, Builder.getInt64Ty());
1072 else if (Cand.V->getType()->isPointerTy())
1073 ToProfile = Builder.CreatePtrToInt(Cand.V, Builder.getInt64Ty());
1074 assert(ToProfile &&
"value profiling Value is of unexpected type");
1077 Name, PointerType::get(
M.getContext(), 0));
1083 Intrinsic::instrprof_value_profile),
1084 {NormalizedNamePtr, Builder.getInt64(FuncInfo.FunctionHash),
1085 ToProfile, Builder.getInt32(Kind), Builder.getInt32(SiteIndex++)},
1094struct PGOUseEdge :
public PGOEdge {
1095 using PGOEdge::PGOEdge;
1097 std::optional<uint64_t>
Count;
1103 std::string infoString()
const {
1105 return PGOEdge::infoString();
1106 return (Twine(PGOEdge::infoString()) +
" Count=" + Twine(*
Count)).str();
1113struct PGOUseBBInfo :
public PGOBBInfo {
1114 std::optional<uint64_t>
Count;
1115 int32_t UnknownCountInEdge = 0;
1116 int32_t UnknownCountOutEdge = 0;
1117 DirectEdges InEdges;
1118 DirectEdges OutEdges;
1120 PGOUseBBInfo(
unsigned IX) : PGOBBInfo(IX) {}
1126 std::string infoString()
const {
1128 return PGOBBInfo::infoString();
1129 return (Twine(PGOBBInfo::infoString()) +
" Count=" + Twine(*
Count)).str();
1133 void addOutEdge(PGOUseEdge *
E) {
1134 OutEdges.push_back(
E);
1135 UnknownCountOutEdge++;
1139 void addInEdge(PGOUseEdge *
E) {
1140 InEdges.push_back(
E);
1141 UnknownCountInEdge++;
1150 for (
const auto &
E : Edges) {
1163 PGOUseFunc(Function &Func,
Module *Modu, TargetLibraryInfo &TLI,
1164 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
1165 BranchProbabilityInfo *BPI, BlockFrequencyInfo *BFIin,
1166 LoopInfo *LI, ProfileSummaryInfo *PSI,
bool IsCS,
1167 bool InstrumentFuncEntry,
bool InstrumentLoopEntries,
1168 bool HasSingleByteCoverage)
1169 :
F(
Func),
M(Modu), BFI(BFIin), PSI(PSI),
1170 FuncInfo(
Func, TLI, ComdatMembers,
false, BPI, BFIin, LI, IsCS,
1171 InstrumentFuncEntry, InstrumentLoopEntries,
1172 HasSingleByteCoverage),
1173 FreqAttr(FFA_Normal), IsCS(IsCS), VPC(
Func, TLI) {}
1175 void handleInstrProfError(
Error Err, uint64_t MismatchedFuncSum);
1180 bool getRecord(IndexedInstrProfReader *PGOReader);
1183 bool readCounters(
bool &AllZeros,
1187 void populateCounters();
1190 void populateCoverage();
1196 void annotateValueSites();
1199 void annotateValueSites(uint32_t Kind);
1202 void annotateIrrLoopHeaderWeights();
1205 enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };
1208 FuncFreqAttr getFuncFreqAttr()
const {
return FreqAttr; }
1211 uint64_t
getFuncHash()
const {
return FuncInfo.FunctionHash; }
1214 NamedInstrProfRecord &getProfileRecord() {
return ProfileRecord; }
1217 PGOUseBBInfo &getBBInfo(
const BasicBlock *BB)
const {
1218 return FuncInfo.getBBInfo(BB);
1222 PGOUseBBInfo *findBBInfo(
const BasicBlock *BB)
const {
1223 return FuncInfo.findBBInfo(BB);
1228 void dumpInfo(StringRef Str =
"")
const { FuncInfo.dumpInfo(Str); }
1230 uint64_t getProgramMaxCount()
const {
return ProgramMaxCount; }
1235 BlockFrequencyInfo *BFI;
1236 ProfileSummaryInfo *PSI;
1239 FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> FuncInfo;
1243 uint64_t ProgramMaxCount;
1246 uint32_t CountPosition = 0;
1249 uint32_t ProfileCountSize = 0;
1252 NamedInstrProfRecord ProfileRecord;
1255 FuncFreqAttr FreqAttr;
1260 ValueProfileCollector VPC;
1263 bool setInstrumentedCounts(
const std::vector<uint64_t> &CountFromProfile);
1267 void setEdgeCount(DirectEdges &Edges, uint64_t
Value);
1272 void markFunctionAttributes(uint64_t EntryCount, uint64_t MaxCount) {
1276 FreqAttr = FFA_Cold;
1284 const FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> &FuncInfo) {
1288 for (
const auto &
E : FuncInfo.MST.allEdges()) {
1293 PGOUseBBInfo &SrcInfo = FuncInfo.getBBInfo(SrcBB);
1294 PGOUseBBInfo &DestInfo = FuncInfo.getBBInfo(DestBB);
1295 SrcInfo.addOutEdge(
E.get());
1296 DestInfo.addInEdge(
E.get());
1302bool PGOUseFunc::setInstrumentedCounts(
1303 const std::vector<uint64_t> &CountFromProfile) {
1305 std::vector<BasicBlock *> InstrumentBBs;
1306 FuncInfo.getInstrumentBBs(InstrumentBBs);
1311 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
1317 auto *FuncEntry = &*
F.begin();
1321 for (BasicBlock *InstrBB : InstrumentBBs) {
1322 uint64_t CountValue = CountFromProfile[
I++];
1323 PGOUseBBInfo &
Info = getBBInfo(InstrBB);
1327 if (InstrBB == FuncEntry && CountValue == 0)
1329 Info.setBBInfoCount(CountValue);
1331 ProfileCountSize = CountFromProfile.size();
1335 auto setEdgeCount = [
this](PGOUseEdge *
E, uint64_t
Value) ->
void {
1337 this->getBBInfo(
E->SrcBB).UnknownCountOutEdge--;
1338 this->getBBInfo(
E->DestBB).UnknownCountInEdge--;
1344 for (
const auto &
E : FuncInfo.MST.allEdges()) {
1345 if (
E->Removed ||
E->InMST)
1348 PGOUseBBInfo &SrcInfo = getBBInfo(SrcBB);
1352 if (SrcInfo.Count && SrcInfo.OutEdges.size() == 1)
1353 setEdgeCount(
E.get(), *SrcInfo.Count);
1356 PGOUseBBInfo &DestInfo = getBBInfo(DestBB);
1359 if (DestInfo.Count && DestInfo.InEdges.size() == 1)
1360 setEdgeCount(
E.get(), *DestInfo.Count);
1366 setEdgeCount(
E.get(), 0);
1373void PGOUseFunc::setEdgeCount(DirectEdges &Edges, uint64_t
Value) {
1374 for (
auto &
E : Edges) {
1379 getBBInfo(
E->SrcBB).UnknownCountOutEdge--;
1380 getBBInfo(
E->DestBB).UnknownCountInEdge--;
1388 const char MetadataName[] =
"instr_prof_hash_mismatch";
1391 auto *Existing =
F.getMetadata(LLVMContext::MD_annotation);
1394 for (
const auto &
N : Tuple->operands()) {
1395 if (
N.equalsStr(MetadataName))
1404 F.setMetadata(LLVMContext::MD_annotation, MD);
1407void PGOUseFunc::handleInstrProfError(
Error Err, uint64_t MismatchedFuncSum) {
1409 auto &Ctx =
M->getContext();
1410 auto Err = IPE.
get();
1411 bool SkipWarning =
false;
1413 << FuncInfo.FuncName <<
": ");
1414 if (Err == instrprof_error::unknown_function) {
1415 IsCS ? NumOfCSPGOMissing++ : NumOfPGOMissing++;
1418 }
else if (Err == instrprof_error::hash_mismatch ||
1419 Err == instrprof_error::malformed) {
1420 IsCS ? NumOfCSPGOMismatch++ : NumOfPGOMismatch++;
1426 LLVM_DEBUG(
dbgs() <<
"hash mismatch (hash= " << FuncInfo.FunctionHash
1427 <<
" skip=" << SkipWarning <<
")");
1437 IPE.
message() + std::string(
" ") +
F.getName().str() +
1438 std::string(
" Hash = ") + std::to_string(FuncInfo.FunctionHash) +
1439 std::string(
" up to ") + std::to_string(MismatchedFuncSum) +
1440 std::string(
" count discarded");
1443 DiagnosticInfoPGOProfile(
M->getName().data(), Msg,
DS_Warning));
1447bool PGOUseFunc::getRecord(IndexedInstrProfReader *PGOReader) {
1448 uint64_t MismatchedFuncSum = 0;
1450 FuncInfo.FuncName, FuncInfo.FunctionHash, FuncInfo.DeprecatedFuncName,
1451 &MismatchedFuncSum);
1453 handleInstrProfError(std::move(
E), MismatchedFuncSum);
1456 ProfileRecord = std::move(
Result.get());
1464bool PGOUseFunc::readCounters(
bool &AllZeros,
1466 auto &Ctx =
M->getContext();
1471 std::vector<uint64_t> &CountFromProfile = ProfileRecord.
Counts;
1473 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1476 uint64_t ValueSum = 0;
1477 for (
unsigned I = 0, S = CountFromProfile.size();
I < S;
I++) {
1479 ValueSum += CountFromProfile[
I];
1481 AllZeros = (ValueSum == 0);
1485 getBBInfo(
nullptr).UnknownCountOutEdge = 2;
1486 getBBInfo(
nullptr).UnknownCountInEdge = 2;
1488 if (!setInstrumentedCounts(CountFromProfile)) {
1490 dbgs() <<
"Inconsistent number of counts, skipping this function");
1491 Ctx.diagnose(DiagnosticInfoPGOProfile(
1492 M->getName().data(),
1493 Twine(
"Inconsistent number of counts in ") +
F.getName().str() +
1494 Twine(
": the profile may be stale or there is a function name "
1502void PGOUseFunc::populateCoverage() {
1503 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1505 ArrayRef<uint64_t> CountsFromProfile = ProfileRecord.
Counts;
1506 DenseMap<const BasicBlock *, bool>
Coverage;
1509 if (FuncInfo.BCI->shouldInstrumentBlock(BB))
1514 DenseMap<const BasicBlock *, DenseSet<const BasicBlock *>>
1515 InverseDependencies;
1516 for (
auto &BB :
F) {
1517 for (
auto *Dep : FuncInfo.BCI->getDependencies(BB)) {
1519 InverseDependencies[Dep].
insert(&BB);
1524 std::stack<const BasicBlock *> CoveredBlocksToProcess;
1525 for (
auto &[BB, IsCovered] : Coverage)
1527 CoveredBlocksToProcess.push(BB);
1529 while (!CoveredBlocksToProcess.empty()) {
1530 auto *CoveredBlock = CoveredBlocksToProcess.top();
1531 assert(Coverage[CoveredBlock]);
1532 CoveredBlocksToProcess.pop();
1533 for (
auto *BB : InverseDependencies[CoveredBlock]) {
1539 CoveredBlocksToProcess.push(BB);
1544 MDBuilder MDB(
F.getContext());
1547 F.setEntryCount(Coverage[&
F.getEntryBlock()] ? 10000 : 0);
1548 for (
auto &BB :
F) {
1555 SmallVector<uint32_t, 4> Weights;
1557 Weights.
push_back((Coverage[Succ] || !Coverage[&BB]) ? 1 : 0);
1558 if (Weights.
size() >= 2)
1563 unsigned NumCorruptCoverage = 0;
1564 DominatorTree DT(
F);
1566 BranchProbabilityInfo BPI(
F, LI);
1567 BlockFrequencyInfo
BFI(
F, BPI, LI);
1568 auto IsBlockDead = [&](
const BasicBlock &BB) -> std::optional<bool> {
1569 if (
auto C =
BFI.getBlockProfileCount(&BB))
1573 LLVM_DEBUG(
dbgs() <<
"Block Coverage: (Instrumented=*, Covered=X)\n");
1574 for (
auto &BB :
F) {
1575 LLVM_DEBUG(
dbgs() << (FuncInfo.BCI->shouldInstrumentBlock(BB) ?
"* " :
" ")
1576 << (Coverage[&BB] ?
"X " :
" ") <<
" " << BB.getName()
1583 if (Cov == IsBlockDead(BB).value_or(
false)) {
1585 dbgs() <<
"Found inconsistent block covearge for " << BB.getName()
1586 <<
": BCI=" << (Cov ?
"Covered" :
"Dead") <<
" BFI="
1587 << (IsBlockDead(BB).value() ?
"Dead" :
"Covered") <<
"\n");
1588 ++NumCorruptCoverage;
1594 auto &Ctx =
M->getContext();
1595 Ctx.diagnose(DiagnosticInfoPGOProfile(
1596 M->getName().data(),
1597 Twine(
"Found inconsistent block coverage for function ") +
F.getName() +
1598 " in " + Twine(NumCorruptCoverage) +
" blocks.",
1602 FuncInfo.BCI->viewBlockCoverageGraph(&Coverage);
1607void PGOUseFunc::populateCounters() {
1608 bool Changes =
true;
1609 unsigned NumPasses = 0;
1617 PGOUseBBInfo *UseBBInfo = findBBInfo(&BB);
1618 if (UseBBInfo ==
nullptr)
1620 if (!UseBBInfo->Count) {
1621 if (UseBBInfo->UnknownCountOutEdge == 0) {
1624 }
else if (UseBBInfo->UnknownCountInEdge == 0) {
1629 if (UseBBInfo->Count) {
1630 if (UseBBInfo->UnknownCountOutEdge == 1) {
1636 if (*UseBBInfo->Count > OutSum)
1637 Total = *UseBBInfo->Count - OutSum;
1638 setEdgeCount(UseBBInfo->OutEdges,
Total);
1641 if (UseBBInfo->UnknownCountInEdge == 1) {
1644 if (*UseBBInfo->Count > InSum)
1645 Total = *UseBBInfo->Count - InSum;
1646 setEdgeCount(UseBBInfo->InEdges,
Total);
1653 LLVM_DEBUG(
dbgs() <<
"Populate counts in " << NumPasses <<
" passes.\n");
1657 for (
auto &BB :
F) {
1658 auto BI = findBBInfo(&BB);
1661 assert(BI->Count &&
"BB count is not valid");
1665 FuncInfo.SIVisitor.annotateSelects(
this, &CountPosition);
1666 assert(CountPosition == ProfileCountSize);
1670 for (
auto &BB :
F) {
1671 auto BI = findBBInfo(&BB);
1674 FuncMaxCount = std::max(FuncMaxCount, *BI->Count);
1683 LLVM_DEBUG(FuncInfo.dumpInfo(
"after reading profile."));
1687void PGOUseFunc::setBranchWeights() {
1689 LLVM_DEBUG(
dbgs() <<
"\nSetting branch weights for func " <<
F.getName()
1690 <<
" IsCS=" << IsCS <<
"\n");
1691 for (
auto &BB :
F) {
1700 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1701 if (!*BBCountInfo.Count)
1708 unsigned OutEdgesCount = BBCountInfo.OutEdges.size();
1709 unsigned SuccessorCount = BB.getTerminator()->getNumSuccessors();
1710 assert(OutEdgesCount <= SuccessorCount);
1713 uint64_t MaxCount = 0;
1714 for (
unsigned It = 0; It < OutEdgesCount; It++) {
1715 const PGOUseEdge *
E = BBCountInfo.OutEdges[It];
1718 if (DestBB ==
nullptr)
1721 uint64_t EdgeCount = *
E->Count;
1722 if (EdgeCount > MaxCount)
1723 MaxCount = EdgeCount;
1724 EdgeCounts[SuccNum] = EdgeCount;
1733 auto &Ctx =
M->getContext();
1734 Ctx.diagnose(DiagnosticInfoPGOProfile(
1735 M->getName().data(),
1736 Twine(
"Profile in ") +
F.getName().str() +
1737 Twine(
" partially ignored") +
1738 Twine(
", possibly due to the lack of a return path."),
1752void PGOUseFunc::annotateIrrLoopHeaderWeights() {
1753 LLVM_DEBUG(
dbgs() <<
"\nAnnotating irreducible loop header weights.\n");
1755 for (
auto &BB :
F) {
1761 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1767void SelectInstVisitor::instrumentOneSelectInst(SelectInst &SI) {
1770 Type *Int64Ty = Builder.getInt64Ty();
1771 auto *Step = Builder.CreateZExt(
SI.getCondition(), Int64Ty);
1772 auto *NormalizedFuncNameVarPtr =
1774 FuncNameVar, PointerType::get(
M->getContext(), 0));
1775 Builder.CreateIntrinsic(Intrinsic::instrprof_increment_step,
1776 {NormalizedFuncNameVarPtr, Builder.getInt64(
FuncHash),
1777 Builder.getInt32(TotalNumCtrs),
1778 Builder.getInt32(*CurCtrIdx), Step});
1782void SelectInstVisitor::annotateOneSelectInst(SelectInst &SI) {
1783 std::vector<uint64_t> &CountFromProfile = UseFunc->getProfileRecord().Counts;
1784 assert(*CurCtrIdx < CountFromProfile.size() &&
1785 "Out of bound access of counters");
1786 uint64_t SCounts[2];
1787 SCounts[0] = CountFromProfile[*CurCtrIdx];
1789 uint64_t TotalCount = 0;
1790 auto BI = UseFunc->findBBInfo(
SI.getParent());
1791 if (BI !=
nullptr) {
1792 TotalCount = *BI->Count;
1795 if (TotalCount < SCounts[0])
1796 BI->Count = SCounts[0];
1799 SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);
1800 uint64_t MaxCount = std::max(SCounts[0], SCounts[1]);
1805void SelectInstVisitor::visitSelectInst(SelectInst &SI) {
1809 if (
SI.getCondition()->getType()->isVectorTy())
1817 instrumentOneSelectInst(SI);
1820 annotateOneSelectInst(SI);
1828 if (ValueProfKind == IPVK_MemOPSize)
1830 if (ValueProfKind == llvm::IPVK_VTableTarget)
1836void PGOUseFunc::annotateValueSites() {
1843 for (uint32_t Kind = IPVK_First;
Kind <= IPVK_Last; ++
Kind)
1844 annotateValueSites(Kind);
1848void PGOUseFunc::annotateValueSites(uint32_t Kind) {
1849 assert(Kind <= IPVK_Last);
1850 unsigned ValueSiteIndex = 0;
1864 NumValueSites != FuncInfo.ValueSites[IPVK_VTableTarget].size() &&
1866 FuncInfo.ValueSites[IPVK_VTableTarget] = VPC.
get(IPVK_VTableTarget);
1867 auto &ValueSites = FuncInfo.ValueSites[
Kind];
1869 auto &Ctx =
M->getContext();
1870 Ctx.diagnose(DiagnosticInfoPGOProfile(
1871 M->getName().data(),
1872 Twine(
"Inconsistent number of value sites for ") +
1875 Twine(
"\", possibly due to the use of a stale profile."),
1881 LLVM_DEBUG(
dbgs() <<
"Read one value site profile (kind = " << Kind
1882 <<
"): Index = " << ValueSiteIndex <<
" out of "
1885 *M, *
I.AnnotatedInst, ProfileRecord,
1896 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
1901 ComdatMembers.insert(std::make_pair(
C, &
F));
1903 if (
Comdat *
C = GV.getComdat())
1904 ComdatMembers.insert(std::make_pair(
C, &GV));
1906 if (
Comdat *
C = GA.getComdat())
1907 ComdatMembers.insert(std::make_pair(
C, &GA));
1912 if (
F.isDeclaration())
1917 unsigned NumCriticalEdges = 0;
1918 for (
auto &BB :
F) {
1927 <<
", NumCriticalEdges=" << NumCriticalEdges
1928 <<
" exceed the threshold. Skip PGO.\n");
1938 if (
F.hasFnAttribute(llvm::Attribute::Naked))
1940 if (
F.hasFnAttribute(llvm::Attribute::NoProfile))
1942 if (
F.hasFnAttribute(llvm::Attribute::SkipProfile))
1947 if (
auto EntryCount =
F.getEntryCount())
1965 Triple TT(M.getTargetTriple());
1970 Twine(
"VTable value profiling is presently not "
1971 "supported for non-ELF object formats"),
1973 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
1983 FunctionInstrumenter FI(M,
F, TLI, ComdatMembers, BPI, BFI, LI,
1984 InstrumentationType);
1997 if (ProfileSampling)
2022 InstrumentationType))
2035 auto BFIEntryCount =
F.getEntryCount();
2036 assert(BFIEntryCount && (BFIEntryCount->getCount() > 0) &&
2037 "Invalid BFI Entrycount");
2041 for (
auto &BBI :
F) {
2044 if (!Func.findBBInfo(&BBI))
2047 CountValue = *Func.getBBInfo(&BBI).Count;
2048 BFICountValue = *BFICount;
2052 if (SumCount.isZero())
2056 "Incorrect sum of BFI counts");
2059 double Scale = (SumCount / SumBFICount).convertToDouble();
2060 if (Scale < 1.001 && Scale > 0.999)
2065 if (NewEntryCount == 0)
2071 << NewEntryCount <<
"\n");
2088 unsigned BBNum = 0, BBMisMatchNum = 0, NonZeroBBNum = 0;
2089 for (
auto &BBI :
F) {
2090 PGOUseBBInfo *BBInfo = Func.findBBInfo(&BBI);
2094 uint64_t CountValue = BBInfo->Count.value_or(CountValue);
2102 BFICountValue = *BFICount;
2105 bool rawIsHot = CountValue >= HotCountThreshold;
2106 bool BFIIsHot = BFICountValue >= HotCountThreshold;
2108 bool ShowCount =
false;
2109 if (rawIsHot && !BFIIsHot) {
2110 Msg =
"raw-Hot to BFI-nonHot";
2112 }
else if (rawIsCold && BFIIsHot) {
2113 Msg =
"raw-Cold to BFI-Hot";
2122 uint64_t Diff = (BFICountValue >= CountValue)
2123 ? BFICountValue - CountValue
2124 : CountValue - BFICountValue;
2132 F.getSubprogram(), &BBI);
2134 <<
" Count=" <<
ore::NV(
"Count", CountValue)
2135 <<
" BFI_Count=" <<
ore::NV(
"Count", BFICountValue);
2137 Remark <<
" (" << Msg <<
")";
2144 F.getSubprogram(), &
F.getEntryBlock())
2145 <<
"In Func " <<
ore::NV(
"Function",
F.getName())
2146 <<
": Num_of_BB=" <<
ore::NV(
"Count", BBNum)
2147 <<
", Num_of_non_zerovalue_BB=" <<
ore::NV(
"Count", NonZeroBBNum)
2148 <<
", Num_of_mis_matching_BB=" <<
ore::NV(
"Count", BBMisMatchNum);
2161 auto &Ctx = M.getContext();
2164 ProfileRemappingFileName);
2165 if (
Error E = ReaderOrErr.takeError()) {
2173 std::unique_ptr<IndexedInstrProfReader> PGOReader =
2174 std::move(ReaderOrErr.get());
2180 if (!PGOReader->hasCSIRLevelProfile() && IsCS)
2184 if (!PGOReader->isIRLevelProfile()) {
2186 ProfileFileName.
data(),
"Not an IR level instrumentation profile"));
2189 if (PGOReader->functionEntryOnly()) {
2191 ProfileFileName.
data(),
2192 "Function entry profiles are not yet supported for optimization"));
2198 if (!
G.hasName() || !
G.hasMetadata(LLVMContext::MD_type))
2209 M.setProfileSummary(PGOReader->getSummary(IsCS).getMD(M.getContext()),
2214 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
2216 std::vector<Function *> HotFunctions;
2217 std::vector<Function *> ColdFunctions;
2221 bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled();
2224 bool InstrumentLoopEntries = PGOReader->instrLoopEntriesEnabled();
2228 bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage();
2236 if (!HasSingleByteCoverage) {
2242 PGOUseFunc Func(
F, &M, TLI, ComdatMembers, BPI, BFI, LI, PSI, IsCS,
2243 InstrumentFuncEntry, InstrumentLoopEntries,
2244 HasSingleByteCoverage);
2245 if (!Func.getRecord(PGOReader.get()))
2247 if (HasSingleByteCoverage) {
2248 Func.populateCoverage();
2256 bool AllZeros =
false;
2257 if (!Func.readCounters(AllZeros, PseudoKind))
2261 if (Func.getProgramMaxCount() != 0)
2262 ColdFunctions.push_back(&
F);
2267 if (
F.hasFnAttribute(Attribute::Cold))
2268 F.removeFnAttr(Attribute::Cold);
2271 F.addFnAttr(Attribute::Hot);
2274 Func.populateCounters();
2275 Func.setBranchWeights();
2276 Func.annotateValueSites();
2277 Func.annotateIrrLoopHeaderWeights();
2278 PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();
2279 if (FreqAttr == PGOUseFunc::FFA_Cold)
2280 ColdFunctions.push_back(&
F);
2281 else if (FreqAttr == PGOUseFunc::FFA_Hot)
2282 HotFunctions.push_back(&
F);
2287 std::unique_ptr<BranchProbabilityInfo> NewBPI =
2288 std::make_unique<BranchProbabilityInfo>(
F, LI);
2289 std::unique_ptr<BlockFrequencyInfo> NewBFI =
2290 std::make_unique<BlockFrequencyInfo>(
F, *NewBPI, LI);
2294 dbgs() <<
"pgo-view-counts: " << Func.getFunc().getName() <<
"\n";
2295 NewBFI->print(
dbgs());
2305 ViewGraph(&Func,
Twine(
"PGORawCounts_") + Func.getFunc().getName());
2307 dbgs() <<
"pgo-view-raw-counts: " << Func.getFunc().getName() <<
"\n";
2334 for (
auto &
F : HotFunctions) {
2335 F->addFnAttr(Attribute::InlineHint);
2336 LLVM_DEBUG(
dbgs() <<
"Set inline attribute to function: " <<
F->getName()
2339 for (
auto &
F : ColdFunctions) {
2342 if (
F->hasFnAttribute(Attribute::Hot)) {
2343 auto &Ctx = M.getContext();
2344 std::string Msg = std::string(
"Function ") +
F->getName().str() +
2345 std::string(
" is annotated as a hot function but"
2346 " the profile is cold");
2351 F->addFnAttr(Attribute::Cold);
2352 LLVM_DEBUG(
dbgs() <<
"Set cold attribute to function: " <<
F->getName()
2359 std::string Filename, std::string RemappingFilename,
bool IsCS,
2361 : ProfileFileName(
std::
move(Filename)),
2362 ProfileRemappingFileName(
std::
move(RemappingFilename)), IsCS(IsCS),
2391 LookupTLI, LookupBPI, LookupBFI, LookupLI, PSI,
2399 if (!
Node->getName().empty())
2400 return Node->getName().str();
2402 std::string SimpleNodeName;
2405 return SimpleNodeName;
2422 if (BrCondStr.empty())
2426 std::accumulate(Weights.begin(), Weights.end(), (
uint64_t)0,
2434 std::string BranchProbStr;
2437 OS <<
" (total count : " << TotalCount <<
")";
2442 << BrCondStr <<
" is true with probability : " << BranchProbStr;
2461 return &
G->getFunc().front();
2484 return std::string(
G->getFunc().getName());
2492 PGOUseBBInfo *BI = Graph->findBBInfo(
Node);
2494 if (BI && BI->Count)
2495 OS << *BI->Count <<
"\\l";
2506 OS <<
"SELECT : { T = ";
2510 OS <<
"Unknown, F = Unknown }\\l";
2512 OS << TC <<
", F = " << FC <<
" }\\l";
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
This file finds the minimum set of blocks on a CFG that must be instrumented to infer execution cover...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
post inline ee instrument
static BasicBlock * getInstrBB(CFGMST< Edge, BBInfo > &MST, Edge &E, const DenseSet< const BasicBlock * > &ExecBlocks)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#define INSTR_PROF_QUOTE(x)
#define VARIANT_MASK_CSIR_PROF
#define VARIANT_MASK_DBG_CORRELATE
#define INSTR_PROF_RAW_VERSION
#define INSTR_PROF_RAW_VERSION_VAR
#define VARIANT_MASK_TEMPORAL_PROF
#define VARIANT_MASK_IR_PROF
#define VARIANT_MASK_BYTE_COVERAGE
#define VARIANT_MASK_INSTR_ENTRY
#define VARIANT_MASK_FUNCTION_ENTRY_ONLY
#define VARIANT_MASK_INSTR_LOOP_ENTRIES
Machine Check Debug Module
static cl::opt< unsigned > ColdCountThreshold("mfs-count-threshold", cl::desc("Minimum number of times a block must be executed to be retained."), cl::init(1), cl::Hidden)
static GlobalVariable * createIRLevelProfileFlagVar(Module &M, PGOInstrumentationType InstrumentationType)
static cl::opt< std::string > PGOTestProfileRemappingFile("pgo-test-profile-remapping-file", cl::init(""), cl::Hidden, cl::value_desc("filename"), cl::desc("Specify the path of profile remapping file. This is mainly for " "test purpose."))
static void fixFuncEntryCount(PGOUseFunc &Func, LoopInfo &LI, BranchProbabilityInfo &NBPI)
static void annotateFunctionWithHashMismatch(Function &F, LLVMContext &ctx)
static cl::opt< unsigned > MaxNumMemOPAnnotations("memop-max-annotations", cl::init(4), cl::Hidden, cl::desc("Max number of precise value annotations for a single memop" "intrinsic"))
static cl::opt< unsigned > MaxNumAnnotations("icp-max-annotations", cl::init(3), cl::Hidden, cl::desc("Max number of annotations for a single indirect " "call callsite"))
static bool skipPGOGen(const Function &F)
static void collectComdatMembers(Module &M, std::unordered_multimap< Comdat *, GlobalValue * > &ComdatMembers)
static void populateEHOperandBundle(VPCandidateInfo &Cand, DenseMap< BasicBlock *, ColorVector > &BlockColors, SmallVectorImpl< OperandBundleDef > &OpBundles)
static void verifyFuncBFI(PGOUseFunc &Func, LoopInfo &LI, BranchProbabilityInfo &NBPI, uint64_t HotCountThreshold, uint64_t ColdCountThreshold)
static cl::opt< bool > DoComdatRenaming("do-comdat-renaming", cl::init(false), cl::Hidden, cl::desc("Append function hash to the name of COMDAT function to avoid " "function hash mismatch due to the preinliner"))
static bool annotateAllFunctions(Module &M, StringRef ProfileFileName, StringRef ProfileRemappingFileName, vfs::FileSystem &FS, function_ref< TargetLibraryInfo &(Function &)> LookupTLI, function_ref< BranchProbabilityInfo *(Function &)> LookupBPI, function_ref< BlockFrequencyInfo *(Function &)> LookupBFI, function_ref< LoopInfo *(Function &)> LookupLI, ProfileSummaryInfo *PSI, bool IsCS)
static void setupBBInfoEdges(const FuncPGOInstrumentation< PGOUseEdge, PGOUseBBInfo > &FuncInfo)
Set up InEdges/OutEdges for all BBs in the MST.
static bool skipPGOUse(const Function &F)
static bool canRenameComdat(Function &F, std::unordered_multimap< Comdat *, GlobalValue * > &ComdatMembers)
ValueProfileCollector::CandidateInfo VPCandidateInfo
static bool InstrumentAllFunctions(Module &M, function_ref< TargetLibraryInfo &(Function &)> LookupTLI, function_ref< BranchProbabilityInfo *(Function &)> LookupBPI, function_ref< BlockFrequencyInfo *(Function &)> LookupBFI, function_ref< LoopInfo *(Function &)> LookupLI, PGOInstrumentationType InstrumentationType)
static uint64_t sumEdgeCount(const ArrayRef< PGOUseEdge * > Edges)
static uint32_t getMaxNumAnnotations(InstrProfValueKind ValueProfKind)
static cl::opt< bool > DisableValueProfiling("disable-vp", cl::init(false), cl::Hidden, cl::desc("Disable Value Profiling"))
static std::string getSimpleNodeName(const BasicBlock *Node)
static bool isIndirectBrTarget(BasicBlock *BB)
static cl::opt< std::string > PGOTestProfileFile("pgo-test-profile-file", cl::init(""), cl::Hidden, cl::value_desc("filename"), cl::desc("Specify the path of profile data file. This is " "mainly for test purpose."))
static std::string getBranchCondString(Instruction *TI)
static const char * ValueProfKindDescr[]
This file provides the interface for IR based instrumentation passes ( (profile-gen,...
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
void visit(MachineFunction &MF, MachineBasicBlock &Start, std::function< void(MachineBasicBlock *)> op)
std::pair< BasicBlock *, BasicBlock * > Edge
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
StringSet - A set-like wrapper for the StringMap.
Defines the virtual file system interface vfs::FileSystem.
void printAsOperand(OutputBuffer &OB, Prec P=Prec::Default, bool StrictlyWorse=false) const
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Class for arbitrary precision integers.
This templated class represents "all analyses that operate over <aparticular IR unit>" (e....
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
LLVM Basic Block Representation.
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI const_iterator getFirstNonPHIOrDbgOrAlloca() const
Returns an iterator to the first instruction in this block that is not a PHINode, a debug intrinsic,...
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...
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const BasicBlock *BB, bool AllowSynthetic=false) const
Returns the estimated profile count of BB.
Conditional or Unconditional Branch instruction.
bool isConditional() const
Value * getCondition() const
Analysis pass which computes BranchProbabilityInfo.
Analysis providing branch probability information.
Edge & addEdge(BasicBlock *Src, BasicBlock *Dest, uint64_t W)
const std::vector< std::unique_ptr< Edge > > & allEdges() const
Predicate getPredicate() const
Return the predicate for this instruction.
LLVM_ABI StringRef getName() const
void setSelectionKind(SelectionKind Val)
SelectionKind getSelectionKind() const
static LLVM_ABI Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
This is the shared class of boolean and integer constants.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Diagnostic information for the PGO profiler.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Base class for error info classes.
virtual std::string message() const
Return the error message as a string.
Lightweight error class with error context and mandatory checking.
Class to represent profile counts.
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
@ HiddenVisibility
The GV is hidden.
@ ProtectedVisibility
The GV is protected.
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
This instruction compares its operands according to the predicate given to the constructor.
static Expected< std::unique_ptr< IndexedInstrProfReader > > create(const Twine &Path, vfs::FileSystem &FS, const Twine &RemappingPath="")
Factory method to create an indexed reader.
uint64_t getMaximumFunctionCount(bool UseCS)
Return the maximum of all known function counts.
Expected< NamedInstrProfRecord > getInstrProfRecord(StringRef FuncName, uint64_t FuncHash, StringRef DeprecatedFuncName="", uint64_t *MismatchedFuncSum=nullptr)
Return the NamedInstrProfRecord associated with FuncName and FuncHash.
Base class for instruction visitors.
static bool canInstrumentCallsite(const CallBase &CB)
instrprof_error get() const
std::string message() const override
Return the error message as a string.
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
LLVM_ABI void update(ArrayRef< uint8_t > Data)
This is an important class for using LLVM in a threaded context.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Analysis pass that exposes the LoopInfo for a function.
LLVM_ABI MDString * createString(StringRef Str)
Return the given string as metadata.
LLVM_ABI MDNode * createIrrLoopHeaderWeight(uint64_t Weight)
Return metadata containing an irreducible loop header weight.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
A Module instance is used to store all the information related to an LLVM module.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
LLVM_ABI PGOInstrumentationUse(std::string Filename="", std::string RemappingFilename="", bool IsCS=false, IntrusiveRefCntPtr< vfs::FileSystem > FS=nullptr)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
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.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Analysis providing profile information.
LLVM_ABI uint64_t getOrCompColdCountThreshold() const
Returns ColdCountThreshold if set.
LLVM_ABI bool isColdCount(uint64_t C) const
Returns true if count C is considered cold.
LLVM_ABI void refresh(std::unique_ptr< ProfileSummary > &&Other=nullptr)
If a summary is provided as argument, use that.
LLVM_ABI bool isHotCount(uint64_t C) const
Returns true if count C is considered hot.
LLVM_ABI uint64_t getOrCompHotCountThreshold() const
Returns HotCountThreshold if set.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
Value * getOperand(unsigned i) const
std::vector< CandidateInfo > get(InstrProfValueKind Kind) const
returns a list of value profiling candidates of the given kind
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
A raw_ostream that writes to an std::string.
The virtual file system interface.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
uint64_t getFuncHash(const FuncRecordTy *Record)
Return the structural hash associated with the function.
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...
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< FuncNode * > Func
friend class Instruction
Iterator for Instructions in a `BasicBlock.
void write64le(void *P, uint64_t V)
LLVM_ABI IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
static cl::opt< bool > PGOTreatUnknownAsCold("pgo-treat-unknown-as-cold", cl::init(false), cl::Hidden, cl::desc("For cold function instrumentation, treat count unknown(e.g. " "unprofiled) functions as cold."))
FunctionAddr VTableAddr Value
static cl::opt< bool > PGOInstrMemOP("pgo-instr-memop", cl::init(true), cl::Hidden, cl::desc("Use this option to turn on/off " "memory intrinsic size profiling."))
LLVM_ABI void setIrrLoopHeaderMetadata(Module *M, Instruction *TI, uint64_t Count)
LLVM_ABI void setProfMetadata(Instruction *TI, ArrayRef< uint64_t > EdgeCounts, uint64_t MaxCount)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
LLVM_ABI std::string getPGOFuncName(const Function &F, bool InLTO=false, uint64_t Version=INSTR_PROF_INDEX_VERSION)
Please use getIRPGOFuncName for LLVM IR instrumentation.
static cl::opt< bool > PGOViewBlockCoverageGraph("pgo-view-block-coverage-graph", cl::desc("Create a dot file of CFGs with block " "coverage inference information"))
LLVM_ABI cl::opt< bool > DebugInfoCorrelate
LLVM_ABI void createPGOFuncNameMetadata(Function &F, StringRef PGOFuncName)
Create the PGOFuncName meta data if PGOFuncName is different from function's raw name.
LLVM_ABI unsigned GetSuccessorNumber(const BasicBlock *BB, const BasicBlock *Succ)
Search for the specified successor of basic block BB and return its position in the terminator instru...
LLVM_ABI std::string getIRPGOFuncName(const Function &F, bool InLTO=false)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
LLVM_ABI void createProfileSamplingVar(Module &M)
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
constexpr from_range_t from_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
LLVM_ABI void createPGONameMetadata(GlobalObject &GO, StringRef PGOName)
Create the PGOName metadata if a global object's PGO name is different from its mangled name.
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
static cl::opt< bool > PGOBlockCoverage("pgo-block-coverage", cl::desc("Use this option to enable basic block coverage instrumentation"))
cl::opt< bool > PGOWarnMissing
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
cl::opt< unsigned > MaxNumVTableAnnotations("icp-max-num-vtables", cl::init(6), cl::Hidden, cl::desc("Max number of vtables annotated for a vtable load instruction."))
static cl::opt< bool > PGOTemporalInstrumentation("pgo-temporal-instrumentation", cl::desc("Use this option to enable temporal instrumentation"))
LLVM_ABI bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr)
cl::opt< bool > EnableVTableProfileUse("enable-vtable-profile-use", cl::init(false), cl::desc("If ThinLTO and WPD is enabled and this option is true, vtable " "profiles will be used by ICP pass for more efficient indirect " "call sequence. If false, type profiles won't be used."))
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
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...
LLVM_ABI std::string getPGOName(const GlobalVariable &V, bool InLTO=false)
cl::opt< std::string > ViewBlockFreqFuncName("view-bfi-func-name", cl::Hidden, cl::desc("The option to specify " "the name of the function " "whose CFG will be displayed."))
LLVM_ABI GlobalVariable * createPGOFuncNameVar(Function &F, StringRef PGOFuncName)
Create and return the global variable for function name used in PGO instrumentation.
LLVM_ABI 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...
auto reverse(ContainerTy &&C)
static cl::opt< bool > EmitBranchProbability("pgo-emit-branch-prob", cl::init(false), cl::Hidden, cl::desc("When this option is on, the annotated " "branch probability will be emitted as " "optimization remarks: -{Rpass|" "pass-remarks}=pgo-instrumentation"))
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr NumValueSites[IPVK_Last+1]
FunctionAddr VTableAddr Count
Function::ProfileCount ProfileCount
static cl::opt< unsigned > PGOVerifyBFIRatio("pgo-verify-bfi-ratio", cl::init(2), cl::Hidden, cl::desc("Set the threshold for pgo-verify-bfi: only print out " "mismatched BFI if the difference percentage is greater than " "this value (in percentage)."))
static cl::opt< bool > PGOInstrumentLoopEntries("pgo-instrument-loop-entries", cl::init(false), cl::Hidden, cl::desc("Force to instrument loop entries."))
static cl::opt< unsigned > PGOFunctionSizeThreshold("pgo-function-size-threshold", cl::Hidden, cl::desc("Do not instrument functions smaller than this threshold."))
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
static cl::opt< bool > PGOFixEntryCount("pgo-fix-entry-count", cl::init(true), cl::Hidden, cl::desc("Fix function entry count in profile use."))
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
static cl::opt< PGOViewCountsType > PGOViewRawCounts("pgo-view-raw-counts", cl::Hidden, cl::desc("A boolean option to show CFG dag or text " "with raw profile counts from " "profile data. See also option " "-pgo-view-counts. To limit graph " "display to only one function, use " "filtering option -view-bfi-func-name."), cl::values(clEnumValN(PGOVCT_None, "none", "do not show."), clEnumValN(PGOVCT_Graph, "graph", "show a graph."), clEnumValN(PGOVCT_Text, "text", "show in text.")))
static cl::opt< bool > PGOVerifyBFI("pgo-verify-bfi", cl::init(false), cl::Hidden, cl::desc("Print out mismatched BFI counts after setting profile metadata " "The print is enabled under -Rpass-analysis=pgo, or " "internal option -pass-remarks-analysis=pgo."))
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...
cl::opt< bool > NoPGOWarnMismatch
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
static cl::opt< uint64_t > PGOColdInstrumentEntryThreshold("pgo-cold-instrument-entry-threshold", cl::init(0), cl::Hidden, cl::desc("For cold function instrumentation, skip instrumenting functions " "whose entry count is above the given value."))
FunctionAddr VTableAddr uintptr_t uintptr_t Data
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
cl::opt< PGOViewCountsType > PGOViewCounts("pgo-view-counts", cl::Hidden, cl::desc("A boolean option to show CFG dag or text with " "block profile counts and branch probabilities " "right after PGO profile annotation step. The " "profile counts are computed using branch " "probabilities from the runtime profile data and " "block frequency propagation algorithm. To view " "the raw counts from the profile, use option " "-pgo-view-raw-counts instead. To limit graph " "display to only one function, use filtering option " "-view-bfi-func-name."), cl::values(clEnumValN(PGOVCT_None, "none", "do not show."), clEnumValN(PGOVCT_Graph, "graph", "show a graph."), clEnumValN(PGOVCT_Text, "text", "show in text.")))
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
OperandBundleDefT< Value * > OperandBundleDef
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
static cl::opt< unsigned > PGOVerifyBFICutoff("pgo-verify-bfi-cutoff", cl::init(5), cl::Hidden, cl::desc("Set the threshold for pgo-verify-bfi: skip the counts whose " "profile count value is below."))
LLVM_ABI BasicBlock * SplitCriticalEdge(Instruction *TI, unsigned SuccNum, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions(), const Twine &BBName="")
If this edge is a critical edge, insert a new node to split the critical edge.
void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)
ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file, then cleanup.
LLVM_ABI bool isCriticalEdge(const Instruction *TI, unsigned SuccNum, bool AllowIdenticalEdges=false)
Return true if the specified edge is a critical edge.
cl::opt< bool > PGOInstrumentColdFunctionOnly
cl::list< std::string > CtxPGOSkipCallsiteInstrument("ctx-prof-skip-callsite-instr", cl::Hidden, cl::desc("Do not instrument callsites to functions in this list. Intended " "for testing."))
LLVM_ABI bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken=false)
Check if we can safely rename this Comdat function.
static cl::opt< bool > PGOInstrSelect("pgo-instr-select", cl::init(true), cl::Hidden, cl::desc("Use this option to turn on/off SELECT " "instruction instrumentation. "))
LLVM_ABI void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
TinyPtrVector< BasicBlock * > ColorVector
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
llvm::cl::opt< llvm::InstrProfCorrelator::ProfCorrelatorKind > ProfileCorrelate
static cl::opt< bool > PGOFunctionEntryCoverage("pgo-function-entry-coverage", cl::Hidden, cl::desc("Use this option to enable function entry coverage instrumentation."))
static cl::opt< unsigned > PGOFunctionCriticalEdgeThreshold("pgo-critical-edge-threshold", cl::init(20000), cl::Hidden, cl::desc("Do not instrument functions with the number of critical edges " " greater than this threshold."))
uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale)
Scale an individual branch count.
static cl::opt< bool > PGOVerifyHotBFI("pgo-verify-hot-bfi", cl::init(false), cl::Hidden, cl::desc("Print out the non-match BFI count if a hot raw profile count " "becomes non-hot, or a cold raw profile count becomes hot. " "The print is enabled under -Rpass-analysis=pgo, or " "internal option -pass-remarks-analysis=pgo."))
SuccIterator< const Instruction, const BasicBlock > const_succ_iterator
uint64_t calculateCountScale(uint64_t MaxCount)
Calculate what to divide by to scale counts.
LLVM_ABI SmallVector< uint32_t > downscaleWeights(ArrayRef< uint64_t > Weights, std::optional< uint64_t > KnownMaxCount=std::nullopt)
downscale the given weights preserving the ratio.
LLVM_ABI bool isGPUProfTarget(const Module &M)
Determines whether module targets a GPU eligable for PGO instrumentation.
cl::opt< bool > EnableVTableValueProfiling("enable-vtable-value-profiling", cl::init(false), cl::desc("If true, the virtual table address will be instrumented to know " "the types of a C++ pointer. The information is used in indirect " "call promotion to do selective vtable-based comparison."))
static cl::opt< bool > PGOInstrumentEntry("pgo-instrument-entry", cl::init(false), cl::Hidden, cl::desc("Force to instrument function entry basicblock."))
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
static cl::opt< std::string > PGOTraceFuncHash("pgo-trace-func-hash", cl::init("-"), cl::Hidden, cl::value_desc("function name"), cl::desc("Trace the hash of the function with this name."))
cl::opt< bool > NoPGOWarnMismatchComdatWeak
Implement std::hash so that hash_code can be used in STL containers.
static constexpr roundingMode rmNearestTiesToEven
static LLVM_ABI const fltSemantics & IEEEdouble() LLVM_READNONE
DOTGraphTraits(bool isSimple=false)
static std::string getGraphName(const PGOUseFunc *G)
std::string getNodeLabel(const BasicBlock *Node, const PGOUseFunc *Graph)
DefaultDOTGraphTraits(bool simple=false)
static ChildIteratorType child_end(const NodeRef N)
static NodeRef getEntryNode(const PGOUseFunc *G)
static ChildIteratorType child_begin(const NodeRef N)
static nodes_iterator nodes_end(const PGOUseFunc *G)
const BasicBlock * NodeRef
static nodes_iterator nodes_begin(const PGOUseFunc *G)
pointer_iterator< Function::const_iterator > nodes_iterator
const_succ_iterator ChildIteratorType
std::vector< uint64_t > Counts
CountPseudoKind getCountPseudoKind() const
uint32_t getNumValueSites(uint32_t ValueKind) const
Return the number of instrumented sites for ValueKind.
static void setCSFlagInHash(uint64_t &FuncHash)
Instruction * AnnotatedInst