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 {
384 M.getTargetTriple().isGPU();
387 bool shouldInstrumentEntryBB()
const {
395 FunctionInstrumenter(
397 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
401 : M(M),
F(
F), TLI(TLI), ComdatMembers(ComdatMembers), BPI(BPI), BFI(BFI),
402 LI(LI), InstrumentationType(InstrumentationType) {}
413 return std::string();
418 return std::string();
430 else if (CV->
isOne())
441#define VALUE_PROF_KIND(Enumerator, Value, Descr) Descr,
474 Triple TT(M.getTargetTriple());
475 if (TT.supportsCOMDAT()) {
477 IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName));
479 return IRLevelVersionVariable;
489enum VisitMode { VM_counting, VM_instrument, VM_annotate };
493struct SelectInstVisitor :
public InstVisitor<SelectInstVisitor> {
496 VisitMode Mode = VM_counting;
497 unsigned *CurCtrIdx =
nullptr;
498 unsigned TotalNumCtrs = 0;
499 GlobalValue *FuncNameVar =
nullptr;
500 uint64_t FuncHash = 0;
501 PGOUseFunc *UseFunc =
nullptr;
502 bool HasSingleByteCoverage;
504 SelectInstVisitor(Function &Func,
bool HasSingleByteCoverage)
505 : F(
Func), HasSingleByteCoverage(HasSingleByteCoverage) {}
507 void countSelects() {
517 void instrumentSelects(
unsigned *Ind,
unsigned TotalNC, GlobalValue *FNV,
519 Mode = VM_instrument;
521 TotalNumCtrs = TotalNC;
528 void annotateSelects(PGOUseFunc *UF,
unsigned *Ind) {
535 void instrumentOneSelectInst(SelectInst &SI);
536 void annotateOneSelectInst(SelectInst &SI);
539 void visitSelectInst(SelectInst &SI);
543 unsigned getNumOfSelectInsts()
const {
return NSIs; }
555 bool Removed =
false;
556 bool IsCritical =
false;
558 PGOEdge(BasicBlock *Src, BasicBlock *Dest, uint64_t W = 1)
559 : SrcBB(Src), DestBB(Dest), Weight(
W) {}
562 std::string infoString()
const {
563 return (Twine(Removed ?
"-" :
" ") + (InMST ?
" " :
"*") +
564 (IsCritical ?
"c" :
" ") +
" W=" + Twine(Weight))
575 PGOBBInfo(
unsigned IX) : Group(this), Index(IX) {}
578 std::string infoString()
const {
579 return (Twine(
"Index=") + Twine(Index)).str();
584template <
class Edge,
class BBInfo>
class FuncPGOInstrumentation {
592 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
594 ValueProfileCollector VPC;
596 void computeCFGHash();
597 void renameComdatFunction();
600 const TargetLibraryInfo &TLI;
601 std::vector<std::vector<VPCandidateInfo>> ValueSites;
602 SelectInstVisitor SIVisitor;
603 std::string FuncName;
604 std::string DeprecatedFuncName;
605 GlobalVariable *FuncNameVar;
608 uint64_t FunctionHash = 0;
611 CFGMST<Edge, BBInfo> MST;
613 const std::optional<BlockCoverageInference> BCI;
615 static std::optional<BlockCoverageInference>
616 constructBCI(Function &Func,
bool HasSingleByteCoverage,
617 bool InstrumentFuncEntry) {
618 if (HasSingleByteCoverage)
619 return BlockCoverageInference(Func, InstrumentFuncEntry);
625 void getInstrumentBBs(std::vector<BasicBlock *> &InstrumentBBs);
632 BBInfo &getBBInfo(
const BasicBlock *BB)
const {
return MST.getBBInfo(BB); }
635 BBInfo *findBBInfo(
const BasicBlock *BB)
const {
return MST.findBBInfo(BB); }
638 void dumpInfo(StringRef Str =
"")
const {
639 MST.dumpEdges(
dbgs(), Twine(
"Dump Function ") + FuncName +
640 " Hash: " + Twine(FunctionHash) +
"\t" + Str);
643 FuncPGOInstrumentation(
644 Function &Func, TargetLibraryInfo &TLI,
645 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
646 bool CreateGlobalVar =
false, BranchProbabilityInfo *BPI =
nullptr,
647 BlockFrequencyInfo *BFI =
nullptr, LoopInfo *LI =
nullptr,
648 bool IsCS =
false,
bool InstrumentFuncEntry =
true,
649 bool InstrumentLoopEntries =
false,
bool HasSingleByteCoverage =
false)
650 : F(
Func), IsCS(IsCS), ComdatMembers(ComdatMembers), VPC(
Func, TLI),
651 TLI(TLI), ValueSites(IPVK_Last + 1),
652 SIVisitor(
Func, HasSingleByteCoverage),
653 MST(F, InstrumentFuncEntry, InstrumentLoopEntries, BPI, BFI, LI),
654 BCI(constructBCI(
Func, HasSingleByteCoverage, InstrumentFuncEntry)) {
656 BCI->viewBlockCoverageGraph();
658 SIVisitor.countSelects();
659 ValueSites[IPVK_MemOPSize] = VPC.get(IPVK_MemOPSize);
661 NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
662 NumOfPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
663 NumOfPGOBB += MST.bbInfoSize();
664 ValueSites[IPVK_IndirectCallTarget] = VPC.get(IPVK_IndirectCallTarget);
666 ValueSites[IPVK_VTableTarget] = VPC.get(IPVK_VTableTarget);
668 NumOfCSPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
669 NumOfCSPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
670 NumOfCSPGOBB += MST.bbInfoSize();
676 if (!ComdatMembers.empty())
677 renameComdatFunction();
680 for (
const auto &
E : MST.allEdges()) {
683 IsCS ? NumOfCSPGOEdge++ : NumOfPGOEdge++;
685 IsCS ? NumOfCSPGOInstrument++ : NumOfPGOInstrument++;
698template <
class Edge,
class BBInfo>
699void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
700 std::vector<uint8_t> Indexes;
704 auto BI = findBBInfo(Succ);
708 for (
int J = 0; J < 4; J++)
709 Indexes.push_back((
uint8_t)(Index >> (J * 8)));
716 auto updateJCH = [&JCH](
uint64_t Num) {
721 updateJCH((
uint64_t)SIVisitor.getNumOfSelectInsts());
722 updateJCH((
uint64_t)ValueSites[IPVK_IndirectCallTarget].
size());
725 updateJCH(BCI->getInstrumentedBlocksHash());
738 LLVM_DEBUG(
dbgs() <<
"Function Hash Computation for " <<
F.getName() <<
":\n"
739 <<
" CRC = " << JC.
getCRC()
740 <<
", Selects = " << SIVisitor.getNumOfSelectInsts()
741 <<
", Edges = " << MST.
numEdges() <<
", ICSites = "
742 << ValueSites[IPVK_IndirectCallTarget].size()
743 <<
", Memops = " << ValueSites[IPVK_MemOPSize].size()
744 <<
", High32 CRC = " << JCH.
getCRC()
745 <<
", Hash = " << FunctionHash <<
"\n";);
748 dbgs() <<
"Funcname=" <<
F.getName() <<
", Hash=" << FunctionHash
749 <<
" in building " <<
F.getParent()->getSourceFileName() <<
"\n";
755 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
767 for (
auto &&CM :
make_range(ComdatMembers.equal_range(
C))) {
777template <
class Edge,
class BBInfo>
778void FuncPGOInstrumentation<Edge, BBInfo>::renameComdatFunction() {
781 std::string OrigName =
F.getName().str();
782 std::string NewFuncName =
784 F.setName(
Twine(NewFuncName));
786 FuncName =
Twine(FuncName +
"." +
Twine(FunctionHash)).
str();
792 if (!
F.hasComdat()) {
794 NewComdat = M->getOrInsertComdat(
StringRef(NewFuncName));
796 F.setComdat(NewComdat);
801 Comdat *OrigComdat =
F.getComdat();
802 std::string NewComdatName =
804 NewComdat = M->getOrInsertComdat(
StringRef(NewComdatName));
807 for (
auto &&CM :
make_range(ComdatMembers.equal_range(OrigComdat))) {
815template <
class Edge,
class BBInfo>
816void FuncPGOInstrumentation<Edge, BBInfo>::getInstrumentBBs(
817 std::vector<BasicBlock *> &InstrumentBBs) {
820 if (BCI->shouldInstrumentBlock(BB))
821 InstrumentBBs.push_back(&BB);
826 std::vector<Edge *> EdgeList;
829 EdgeList.push_back(
E.get());
831 for (
auto &
E : EdgeList) {
834 InstrumentBBs.push_back(InstrBB);
840template <
class Edge,
class BBInfo>
841BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *
E) {
842 if (
E->InMST ||
E->Removed)
848 if (SrcBB ==
nullptr)
850 if (DestBB ==
nullptr)
865 return canInstrument(SrcBB);
867 return canInstrument(DestBB);
876 dbgs() <<
"Fail to split critical edge: not instrument this edge.\n");
881 IsCS ? NumOfCSPGOSplit++ : NumOfPGOSplit++;
882 LLVM_DEBUG(
dbgs() <<
"Split critical edge: " << getBBInfo(SrcBB).Index
883 <<
" --> " << getBBInfo(DestBB).Index <<
"\n");
885 MST.
addEdge(SrcBB, InstrBB, 0);
887 Edge &NewEdge1 = MST.
addEdge(InstrBB, DestBB, 0);
888 NewEdge1.InMST =
true;
891 return canInstrument(InstrBB);
910 std::optional<OperandBundleUse> ParentFunclet =
918 if (!BlockColors.
empty()) {
919 const ColorVector &CV = BlockColors.
find(OrigCall->getParent())->second;
920 assert(CV.
size() == 1 &&
"non-unique color for block!");
922 if (EHPadIt->isEHPad())
930void FunctionInstrumenter::instrument() {
937 const bool IsCtxProf = InstrumentationType == PGOInstrumentationType::CTXPROF;
938 FuncPGOInstrumentation<PGOEdge, PGOBBInfo> FuncInfo(
939 F, TLI, ComdatMembers, !IsCtxProf, BPI, BFI, LI,
940 InstrumentationType == PGOInstrumentationType::CSFDO,
941 shouldInstrumentEntryBB(), shouldInstrumentLoopEntries(),
945 auto *
const CFGHash =
946 ConstantInt::get(Type::getInt64Ty(
M.getContext()), FuncInfo.FunctionHash);
950 Name, PointerType::get(
M.getContext(), 0));
952 auto &EntryBB =
F.getEntryBlock();
953 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstNonPHIOrDbgOrAlloca());
956 Builder.CreateIntrinsic(
957 Intrinsic::instrprof_cover,
958 {NormalizedNamePtr, CFGHash, Builder.getInt32(1), Builder.getInt32(0)});
962 std::vector<BasicBlock *> InstrumentBBs;
963 FuncInfo.getInstrumentBBs(InstrumentBBs);
965 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
980 auto Visit = [&](llvm::function_ref<void(CallBase * CB)> Visitor) {
982 for (
auto &Instr : BB)
986 if (CS->getCalledFunction() &&
987 SkipCSInstr.contains(CS->getCalledFunction()->getName()))
993 uint32_t TotalNumCallsites = 0;
994 Visit([&TotalNumCallsites](
auto *) { ++TotalNumCallsites; });
998 Visit([&](
auto *CB) {
1000 Builder.CreateCall(CSIntrinsic,
1001 {
Name, CFGHash, Builder.getInt32(TotalNumCallsites),
1003 CB->getCalledOperand()});
1010 auto &EntryBB =
F.getEntryBlock();
1011 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstNonPHIOrDbgOrAlloca());
1014 Builder.CreateIntrinsic(Intrinsic::instrprof_timestamp,
1015 {NormalizedNamePtr, CFGHash,
1017 Builder.getInt32(
I)});
1021 for (
auto *InstrBB : InstrumentBBs) {
1023 assert(Builder.GetInsertPoint() != InstrBB->
end() &&
1024 "Cannot get the Instrumentation point");
1028 : Intrinsic::instrprof_increment,
1029 {NormalizedNamePtr, CFGHash,
1031 Builder.getInt32(
I++)});
1035 FuncInfo.SIVisitor.instrumentSelects(&
I,
NumCounters, Name,
1036 FuncInfo.FunctionHash);
1039 if (isValueProfilingDisabled())
1042 NumOfPGOICall += FuncInfo.ValueSites[IPVK_IndirectCallTarget].size();
1048 DenseMap<BasicBlock *, ColorVector> BlockColors;
1049 if (
F.hasPersonalityFn() &&
1054 for (uint32_t Kind = IPVK_First;
Kind <= IPVK_Last; ++
Kind) {
1055 unsigned SiteIndex = 0;
1061 <<
" site: CallSite Index = " << SiteIndex <<
"\n");
1064 assert(Builder.GetInsertPoint() != Cand.InsertPt->getParent()->end() &&
1065 "Cannot get the Instrumentation point");
1067 Value *ToProfile =
nullptr;
1068 if (Cand.V->getType()->isIntegerTy())
1069 ToProfile = Builder.CreateZExtOrTrunc(Cand.V, Builder.getInt64Ty());
1070 else if (Cand.V->getType()->isPointerTy())
1071 ToProfile = Builder.CreatePtrToInt(Cand.V, Builder.getInt64Ty());
1072 assert(ToProfile &&
"value profiling Value is of unexpected type");
1075 Name, PointerType::get(
M.getContext(), 0));
1081 Intrinsic::instrprof_value_profile),
1082 {NormalizedNamePtr, Builder.getInt64(FuncInfo.FunctionHash),
1083 ToProfile, Builder.getInt32(Kind), Builder.getInt32(SiteIndex++)},
1092struct PGOUseEdge :
public PGOEdge {
1093 using PGOEdge::PGOEdge;
1095 std::optional<uint64_t>
Count;
1101 std::string infoString()
const {
1103 return PGOEdge::infoString();
1104 return (Twine(PGOEdge::infoString()) +
" Count=" + Twine(*
Count)).str();
1111struct PGOUseBBInfo :
public PGOBBInfo {
1112 std::optional<uint64_t>
Count;
1113 int32_t UnknownCountInEdge = 0;
1114 int32_t UnknownCountOutEdge = 0;
1115 DirectEdges InEdges;
1116 DirectEdges OutEdges;
1118 PGOUseBBInfo(
unsigned IX) : PGOBBInfo(IX) {}
1124 std::string infoString()
const {
1126 return PGOBBInfo::infoString();
1127 return (Twine(PGOBBInfo::infoString()) +
" Count=" + Twine(*
Count)).str();
1131 void addOutEdge(PGOUseEdge *
E) {
1132 OutEdges.push_back(
E);
1133 UnknownCountOutEdge++;
1137 void addInEdge(PGOUseEdge *
E) {
1138 InEdges.push_back(
E);
1139 UnknownCountInEdge++;
1148 for (
const auto &
E : Edges) {
1161 PGOUseFunc(Function &Func,
Module *Modu, TargetLibraryInfo &TLI,
1162 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
1163 BranchProbabilityInfo *BPI, BlockFrequencyInfo *BFIin,
1164 LoopInfo *LI, ProfileSummaryInfo *PSI,
bool IsCS,
1165 bool InstrumentFuncEntry,
bool InstrumentLoopEntries,
1166 bool HasSingleByteCoverage)
1167 :
F(
Func),
M(Modu), BFI(BFIin), PSI(PSI),
1168 FuncInfo(
Func, TLI, ComdatMembers,
false, BPI, BFIin, LI, IsCS,
1169 InstrumentFuncEntry, InstrumentLoopEntries,
1170 HasSingleByteCoverage),
1171 FreqAttr(FFA_Normal), IsCS(IsCS), VPC(
Func, TLI) {}
1173 void handleInstrProfError(
Error Err, uint64_t MismatchedFuncSum);
1178 bool getRecord(IndexedInstrProfReader *PGOReader);
1181 bool readCounters(
bool &AllZeros,
1185 void populateCounters();
1188 void populateCoverage();
1194 void annotateValueSites();
1197 void annotateValueSites(uint32_t Kind);
1200 void annotateIrrLoopHeaderWeights();
1203 enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };
1206 FuncFreqAttr getFuncFreqAttr()
const {
return FreqAttr; }
1209 uint64_t
getFuncHash()
const {
return FuncInfo.FunctionHash; }
1212 NamedInstrProfRecord &getProfileRecord() {
return ProfileRecord; }
1215 PGOUseBBInfo &getBBInfo(
const BasicBlock *BB)
const {
1216 return FuncInfo.getBBInfo(BB);
1220 PGOUseBBInfo *findBBInfo(
const BasicBlock *BB)
const {
1221 return FuncInfo.findBBInfo(BB);
1226 void dumpInfo(StringRef Str =
"")
const { FuncInfo.dumpInfo(Str); }
1228 uint64_t getProgramMaxCount()
const {
return ProgramMaxCount; }
1233 BlockFrequencyInfo *BFI;
1234 ProfileSummaryInfo *PSI;
1237 FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> FuncInfo;
1241 uint64_t ProgramMaxCount;
1244 uint32_t CountPosition = 0;
1247 uint32_t ProfileCountSize = 0;
1250 NamedInstrProfRecord ProfileRecord;
1253 FuncFreqAttr FreqAttr;
1258 ValueProfileCollector VPC;
1261 bool setInstrumentedCounts(
const std::vector<uint64_t> &CountFromProfile);
1265 void setEdgeCount(DirectEdges &Edges, uint64_t
Value);
1270 void markFunctionAttributes(uint64_t EntryCount, uint64_t MaxCount) {
1274 FreqAttr = FFA_Cold;
1282 const FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> &FuncInfo) {
1286 for (
const auto &
E : FuncInfo.MST.allEdges()) {
1291 PGOUseBBInfo &SrcInfo = FuncInfo.getBBInfo(SrcBB);
1292 PGOUseBBInfo &DestInfo = FuncInfo.getBBInfo(DestBB);
1293 SrcInfo.addOutEdge(
E.get());
1294 DestInfo.addInEdge(
E.get());
1300bool PGOUseFunc::setInstrumentedCounts(
1301 const std::vector<uint64_t> &CountFromProfile) {
1303 std::vector<BasicBlock *> InstrumentBBs;
1304 FuncInfo.getInstrumentBBs(InstrumentBBs);
1309 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
1315 auto *FuncEntry = &*
F.begin();
1319 for (BasicBlock *InstrBB : InstrumentBBs) {
1320 uint64_t CountValue = CountFromProfile[
I++];
1321 PGOUseBBInfo &
Info = getBBInfo(InstrBB);
1325 if (InstrBB == FuncEntry && CountValue == 0)
1327 Info.setBBInfoCount(CountValue);
1329 ProfileCountSize = CountFromProfile.size();
1333 auto setEdgeCount = [
this](PGOUseEdge *
E, uint64_t
Value) ->
void {
1335 this->getBBInfo(
E->SrcBB).UnknownCountOutEdge--;
1336 this->getBBInfo(
E->DestBB).UnknownCountInEdge--;
1342 for (
const auto &
E : FuncInfo.MST.allEdges()) {
1343 if (
E->Removed ||
E->InMST)
1346 PGOUseBBInfo &SrcInfo = getBBInfo(SrcBB);
1350 if (SrcInfo.Count && SrcInfo.OutEdges.size() == 1)
1351 setEdgeCount(
E.get(), *SrcInfo.Count);
1354 PGOUseBBInfo &DestInfo = getBBInfo(DestBB);
1357 if (DestInfo.Count && DestInfo.InEdges.size() == 1)
1358 setEdgeCount(
E.get(), *DestInfo.Count);
1364 setEdgeCount(
E.get(), 0);
1371void PGOUseFunc::setEdgeCount(DirectEdges &Edges, uint64_t
Value) {
1372 for (
auto &
E : Edges) {
1377 getBBInfo(
E->SrcBB).UnknownCountOutEdge--;
1378 getBBInfo(
E->DestBB).UnknownCountInEdge--;
1386 const char MetadataName[] =
"instr_prof_hash_mismatch";
1389 auto *Existing =
F.getMetadata(LLVMContext::MD_annotation);
1392 for (
const auto &
N : Tuple->operands()) {
1393 if (
N.equalsStr(MetadataName))
1402 F.setMetadata(LLVMContext::MD_annotation, MD);
1405void PGOUseFunc::handleInstrProfError(
Error Err, uint64_t MismatchedFuncSum) {
1407 auto &Ctx =
M->getContext();
1408 auto Err = IPE.
get();
1409 bool SkipWarning =
false;
1411 << FuncInfo.FuncName <<
": ");
1412 if (Err == instrprof_error::unknown_function) {
1413 IsCS ? NumOfCSPGOMissing++ : NumOfPGOMissing++;
1416 }
else if (Err == instrprof_error::hash_mismatch ||
1417 Err == instrprof_error::malformed) {
1418 IsCS ? NumOfCSPGOMismatch++ : NumOfPGOMismatch++;
1424 LLVM_DEBUG(
dbgs() <<
"hash mismatch (hash= " << FuncInfo.FunctionHash
1425 <<
" skip=" << SkipWarning <<
")");
1435 IPE.
message() + std::string(
" ") +
F.getName().str() +
1436 std::string(
" Hash = ") + std::to_string(FuncInfo.FunctionHash) +
1437 std::string(
" up to ") + std::to_string(MismatchedFuncSum) +
1438 std::string(
" count discarded");
1441 DiagnosticInfoPGOProfile(
M->getName().data(), Msg,
DS_Warning));
1445bool PGOUseFunc::getRecord(IndexedInstrProfReader *PGOReader) {
1446 uint64_t MismatchedFuncSum = 0;
1448 FuncInfo.FuncName, FuncInfo.FunctionHash, FuncInfo.DeprecatedFuncName,
1449 &MismatchedFuncSum);
1451 handleInstrProfError(std::move(
E), MismatchedFuncSum);
1454 ProfileRecord = std::move(
Result.get());
1462bool PGOUseFunc::readCounters(
bool &AllZeros,
1464 auto &Ctx =
M->getContext();
1469 std::vector<uint64_t> &CountFromProfile = ProfileRecord.
Counts;
1471 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1474 uint64_t ValueSum = 0;
1475 for (
unsigned I = 0, S = CountFromProfile.size();
I < S;
I++) {
1477 ValueSum += CountFromProfile[
I];
1479 AllZeros = (ValueSum == 0);
1483 getBBInfo(
nullptr).UnknownCountOutEdge = 2;
1484 getBBInfo(
nullptr).UnknownCountInEdge = 2;
1486 if (!setInstrumentedCounts(CountFromProfile)) {
1488 dbgs() <<
"Inconsistent number of counts, skipping this function");
1489 Ctx.diagnose(DiagnosticInfoPGOProfile(
1490 M->getName().data(),
1491 Twine(
"Inconsistent number of counts in ") +
F.getName().str() +
1492 Twine(
": the profile may be stale or there is a function name "
1500void PGOUseFunc::populateCoverage() {
1501 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1503 ArrayRef<uint64_t> CountsFromProfile = ProfileRecord.
Counts;
1504 DenseMap<const BasicBlock *, bool>
Coverage;
1507 if (FuncInfo.BCI->shouldInstrumentBlock(BB))
1512 DenseMap<const BasicBlock *, DenseSet<const BasicBlock *>>
1513 InverseDependencies;
1514 for (
auto &BB :
F) {
1515 for (
auto *Dep : FuncInfo.BCI->getDependencies(BB)) {
1517 InverseDependencies[Dep].
insert(&BB);
1522 std::stack<const BasicBlock *> CoveredBlocksToProcess;
1523 for (
auto &[BB, IsCovered] : Coverage)
1525 CoveredBlocksToProcess.push(BB);
1527 while (!CoveredBlocksToProcess.empty()) {
1528 auto *CoveredBlock = CoveredBlocksToProcess.top();
1529 assert(Coverage[CoveredBlock]);
1530 CoveredBlocksToProcess.pop();
1531 for (
auto *BB : InverseDependencies[CoveredBlock]) {
1537 CoveredBlocksToProcess.push(BB);
1542 MDBuilder MDB(
F.getContext());
1545 F.setEntryCount(Coverage[&
F.getEntryBlock()] ? 10000 : 0);
1546 for (
auto &BB :
F) {
1553 SmallVector<uint32_t, 4> Weights;
1555 Weights.
push_back((Coverage[Succ] || !Coverage[&BB]) ? 1 : 0);
1556 if (Weights.
size() >= 2)
1561 unsigned NumCorruptCoverage = 0;
1562 DominatorTree DT(
F);
1564 BranchProbabilityInfo BPI(
F, LI);
1565 BlockFrequencyInfo BFI(
F, BPI, LI);
1566 auto IsBlockDead = [&](
const BasicBlock &BB) -> std::optional<bool> {
1571 LLVM_DEBUG(
dbgs() <<
"Block Coverage: (Instrumented=*, Covered=X)\n");
1572 for (
auto &BB :
F) {
1573 LLVM_DEBUG(
dbgs() << (FuncInfo.BCI->shouldInstrumentBlock(BB) ?
"* " :
" ")
1574 << (Coverage[&BB] ?
"X " :
" ") <<
" " << BB.getName()
1581 if (Cov == IsBlockDead(BB).value_or(
false)) {
1583 dbgs() <<
"Found inconsistent block covearge for " << BB.getName()
1584 <<
": BCI=" << (Cov ?
"Covered" :
"Dead") <<
" BFI="
1585 << (IsBlockDead(BB).value() ?
"Dead" :
"Covered") <<
"\n");
1586 ++NumCorruptCoverage;
1592 auto &Ctx =
M->getContext();
1593 Ctx.diagnose(DiagnosticInfoPGOProfile(
1594 M->getName().data(),
1595 Twine(
"Found inconsistent block coverage for function ") +
F.getName() +
1596 " in " + Twine(NumCorruptCoverage) +
" blocks.",
1600 FuncInfo.BCI->viewBlockCoverageGraph(&Coverage);
1605void PGOUseFunc::populateCounters() {
1606 bool Changes =
true;
1607 unsigned NumPasses = 0;
1615 PGOUseBBInfo *UseBBInfo = findBBInfo(&BB);
1616 if (UseBBInfo ==
nullptr)
1618 if (!UseBBInfo->Count) {
1619 if (UseBBInfo->UnknownCountOutEdge == 0) {
1622 }
else if (UseBBInfo->UnknownCountInEdge == 0) {
1627 if (UseBBInfo->Count) {
1628 if (UseBBInfo->UnknownCountOutEdge == 1) {
1634 if (*UseBBInfo->Count > OutSum)
1635 Total = *UseBBInfo->Count - OutSum;
1636 setEdgeCount(UseBBInfo->OutEdges,
Total);
1639 if (UseBBInfo->UnknownCountInEdge == 1) {
1642 if (*UseBBInfo->Count > InSum)
1643 Total = *UseBBInfo->Count - InSum;
1644 setEdgeCount(UseBBInfo->InEdges,
Total);
1651 LLVM_DEBUG(
dbgs() <<
"Populate counts in " << NumPasses <<
" passes.\n");
1655 for (
auto &BB :
F) {
1656 auto BI = findBBInfo(&BB);
1659 assert(BI->Count &&
"BB count is not valid");
1663 FuncInfo.SIVisitor.annotateSelects(
this, &CountPosition);
1664 assert(CountPosition == ProfileCountSize);
1668 for (
auto &BB :
F) {
1669 auto BI = findBBInfo(&BB);
1672 FuncMaxCount = std::max(FuncMaxCount, *BI->Count);
1681 LLVM_DEBUG(FuncInfo.dumpInfo(
"after reading profile."));
1685void PGOUseFunc::setBranchWeights() {
1687 LLVM_DEBUG(
dbgs() <<
"\nSetting branch weights for func " <<
F.getName()
1688 <<
" IsCS=" << IsCS <<
"\n");
1689 for (
auto &BB :
F) {
1698 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1699 if (!*BBCountInfo.Count)
1706 unsigned OutEdgesCount = BBCountInfo.OutEdges.size();
1707 unsigned SuccessorCount = BB.getTerminator()->getNumSuccessors();
1708 assert(OutEdgesCount <= SuccessorCount);
1711 uint64_t MaxCount = 0;
1712 for (
unsigned It = 0; It < OutEdgesCount; It++) {
1713 const PGOUseEdge *
E = BBCountInfo.OutEdges[It];
1716 if (DestBB ==
nullptr)
1719 uint64_t EdgeCount = *
E->Count;
1720 if (EdgeCount > MaxCount)
1721 MaxCount = EdgeCount;
1722 EdgeCounts[SuccNum] = EdgeCount;
1731 auto &Ctx =
M->getContext();
1732 Ctx.diagnose(DiagnosticInfoPGOProfile(
1733 M->getName().data(),
1734 Twine(
"Profile in ") +
F.getName().str() +
1735 Twine(
" partially ignored") +
1736 Twine(
", possibly due to the lack of a return path."),
1750void PGOUseFunc::annotateIrrLoopHeaderWeights() {
1751 LLVM_DEBUG(
dbgs() <<
"\nAnnotating irreducible loop header weights.\n");
1753 for (
auto &BB :
F) {
1759 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1765void SelectInstVisitor::instrumentOneSelectInst(SelectInst &SI) {
1768 Type *Int64Ty = Builder.getInt64Ty();
1769 auto *Step = Builder.CreateZExt(
SI.getCondition(), Int64Ty);
1770 auto *NormalizedFuncNameVarPtr =
1772 FuncNameVar, PointerType::get(
M->getContext(), 0));
1773 Builder.CreateIntrinsic(Intrinsic::instrprof_increment_step,
1774 {NormalizedFuncNameVarPtr, Builder.getInt64(
FuncHash),
1775 Builder.getInt32(TotalNumCtrs),
1776 Builder.getInt32(*CurCtrIdx), Step});
1780void SelectInstVisitor::annotateOneSelectInst(SelectInst &SI) {
1781 std::vector<uint64_t> &CountFromProfile = UseFunc->getProfileRecord().Counts;
1782 assert(*CurCtrIdx < CountFromProfile.size() &&
1783 "Out of bound access of counters");
1784 uint64_t SCounts[2];
1785 SCounts[0] = CountFromProfile[*CurCtrIdx];
1787 uint64_t TotalCount = 0;
1788 auto BI = UseFunc->findBBInfo(
SI.getParent());
1789 if (BI !=
nullptr) {
1790 TotalCount = *BI->Count;
1793 if (TotalCount < SCounts[0])
1794 BI->Count = SCounts[0];
1797 SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);
1798 uint64_t MaxCount = std::max(SCounts[0], SCounts[1]);
1803void SelectInstVisitor::visitSelectInst(SelectInst &SI) {
1807 if (
SI.getCondition()->getType()->isVectorTy())
1815 instrumentOneSelectInst(SI);
1818 annotateOneSelectInst(SI);
1826 if (ValueProfKind == IPVK_MemOPSize)
1828 if (ValueProfKind == llvm::IPVK_VTableTarget)
1834void PGOUseFunc::annotateValueSites() {
1841 for (uint32_t Kind = IPVK_First;
Kind <= IPVK_Last; ++
Kind)
1842 annotateValueSites(Kind);
1846void PGOUseFunc::annotateValueSites(uint32_t Kind) {
1847 assert(Kind <= IPVK_Last);
1848 unsigned ValueSiteIndex = 0;
1862 NumValueSites != FuncInfo.ValueSites[IPVK_VTableTarget].size() &&
1864 FuncInfo.ValueSites[IPVK_VTableTarget] = VPC.
get(IPVK_VTableTarget);
1865 auto &ValueSites = FuncInfo.ValueSites[
Kind];
1867 auto &Ctx =
M->getContext();
1868 Ctx.diagnose(DiagnosticInfoPGOProfile(
1869 M->getName().data(),
1870 Twine(
"Inconsistent number of value sites for ") +
1873 Twine(
"\", possibly due to the use of a stale profile."),
1879 LLVM_DEBUG(
dbgs() <<
"Read one value site profile (kind = " << Kind
1880 <<
"): Index = " << ValueSiteIndex <<
" out of "
1883 *M, *
I.AnnotatedInst, ProfileRecord,
1894 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
1899 ComdatMembers.insert(std::make_pair(
C, &
F));
1901 if (
Comdat *
C = GV.getComdat())
1902 ComdatMembers.insert(std::make_pair(
C, &GV));
1904 if (
Comdat *
C = GA.getComdat())
1905 ComdatMembers.insert(std::make_pair(
C, &GA));
1910 if (
F.isDeclaration())
1915 unsigned NumCriticalEdges = 0;
1916 for (
auto &BB :
F) {
1925 <<
", NumCriticalEdges=" << NumCriticalEdges
1926 <<
" exceed the threshold. Skip PGO.\n");
1936 if (
F.hasFnAttribute(llvm::Attribute::Naked))
1938 if (
F.hasFnAttribute(llvm::Attribute::NoProfile))
1940 if (
F.hasFnAttribute(llvm::Attribute::SkipProfile))
1945 if (
auto EntryCount =
F.getEntryCount())
1963 Triple TT(M.getTargetTriple());
1968 Twine(
"VTable value profiling is presently not "
1969 "supported for non-ELF object formats"),
1971 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
1981 FunctionInstrumenter FI(M,
F, TLI, ComdatMembers, BPI, BFI, LI,
1982 InstrumentationType);
1995 if (ProfileSampling)
2020 InstrumentationType))
2033 auto BFIEntryCount =
F.getEntryCount();
2034 assert(BFIEntryCount && (BFIEntryCount->getCount() > 0) &&
2035 "Invalid BFI Entrycount");
2039 for (
auto &BBI :
F) {
2042 if (!Func.findBBInfo(&BBI))
2045 CountValue = *Func.getBBInfo(&BBI).Count;
2046 BFICountValue = *BFICount;
2050 if (SumCount.isZero())
2054 "Incorrect sum of BFI counts");
2057 double Scale = (SumCount / SumBFICount).convertToDouble();
2058 if (Scale < 1.001 && Scale > 0.999)
2063 if (NewEntryCount == 0)
2069 << NewEntryCount <<
"\n");
2086 unsigned BBNum = 0, BBMisMatchNum = 0, NonZeroBBNum = 0;
2087 for (
auto &BBI :
F) {
2088 PGOUseBBInfo *BBInfo = Func.findBBInfo(&BBI);
2092 uint64_t CountValue = BBInfo->Count.value_or(CountValue);
2100 BFICountValue = *BFICount;
2103 bool rawIsHot = CountValue >= HotCountThreshold;
2104 bool BFIIsHot = BFICountValue >= HotCountThreshold;
2106 bool ShowCount =
false;
2107 if (rawIsHot && !BFIIsHot) {
2108 Msg =
"raw-Hot to BFI-nonHot";
2110 }
else if (rawIsCold && BFIIsHot) {
2111 Msg =
"raw-Cold to BFI-Hot";
2120 uint64_t Diff = (BFICountValue >= CountValue)
2121 ? BFICountValue - CountValue
2122 : CountValue - BFICountValue;
2130 F.getSubprogram(), &BBI);
2132 <<
" Count=" <<
ore::NV(
"Count", CountValue)
2133 <<
" BFI_Count=" <<
ore::NV(
"Count", BFICountValue);
2135 Remark <<
" (" << Msg <<
")";
2142 F.getSubprogram(), &
F.getEntryBlock())
2143 <<
"In Func " <<
ore::NV(
"Function",
F.getName())
2144 <<
": Num_of_BB=" <<
ore::NV(
"Count", BBNum)
2145 <<
", Num_of_non_zerovalue_BB=" <<
ore::NV(
"Count", NonZeroBBNum)
2146 <<
", Num_of_mis_matching_BB=" <<
ore::NV(
"Count", BBMisMatchNum);
2159 auto &Ctx = M.getContext();
2162 ProfileRemappingFileName);
2163 if (
Error E = ReaderOrErr.takeError()) {
2171 std::unique_ptr<IndexedInstrProfReader> PGOReader =
2172 std::move(ReaderOrErr.get());
2178 if (!PGOReader->hasCSIRLevelProfile() && IsCS)
2182 if (!PGOReader->isIRLevelProfile()) {
2184 ProfileFileName.
data(),
"Not an IR level instrumentation profile"));
2187 if (PGOReader->functionEntryOnly()) {
2189 ProfileFileName.
data(),
2190 "Function entry profiles are not yet supported for optimization"));
2196 if (!
G.hasName() || !
G.hasMetadata(LLVMContext::MD_type))
2207 M.setProfileSummary(PGOReader->getSummary(IsCS).getMD(M.getContext()),
2212 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
2214 std::vector<Function *> HotFunctions;
2215 std::vector<Function *> ColdFunctions;
2219 bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled();
2222 bool InstrumentLoopEntries = PGOReader->instrLoopEntriesEnabled();
2226 bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage();
2234 if (!HasSingleByteCoverage) {
2240 PGOUseFunc Func(
F, &M, TLI, ComdatMembers, BPI, BFI, LI, PSI, IsCS,
2241 InstrumentFuncEntry, InstrumentLoopEntries,
2242 HasSingleByteCoverage);
2243 if (!Func.getRecord(PGOReader.get()))
2245 if (HasSingleByteCoverage) {
2246 Func.populateCoverage();
2254 bool AllZeros =
false;
2255 if (!Func.readCounters(AllZeros, PseudoKind))
2259 if (Func.getProgramMaxCount() != 0)
2260 ColdFunctions.push_back(&
F);
2265 if (
F.hasFnAttribute(Attribute::Cold))
2266 F.removeFnAttr(Attribute::Cold);
2269 F.addFnAttr(Attribute::Hot);
2272 Func.populateCounters();
2273 Func.setBranchWeights();
2274 Func.annotateValueSites();
2275 Func.annotateIrrLoopHeaderWeights();
2276 PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();
2277 if (FreqAttr == PGOUseFunc::FFA_Cold)
2278 ColdFunctions.push_back(&
F);
2279 else if (FreqAttr == PGOUseFunc::FFA_Hot)
2280 HotFunctions.push_back(&
F);
2285 std::unique_ptr<BranchProbabilityInfo> NewBPI =
2286 std::make_unique<BranchProbabilityInfo>(
F, LI);
2287 std::unique_ptr<BlockFrequencyInfo> NewBFI =
2288 std::make_unique<BlockFrequencyInfo>(
F, *NewBPI, LI);
2292 dbgs() <<
"pgo-view-counts: " << Func.getFunc().getName() <<
"\n";
2293 NewBFI->print(
dbgs());
2303 ViewGraph(&Func,
Twine(
"PGORawCounts_") + Func.getFunc().getName());
2305 dbgs() <<
"pgo-view-raw-counts: " << Func.getFunc().getName() <<
"\n";
2332 for (
auto &
F : HotFunctions) {
2333 F->addFnAttr(Attribute::InlineHint);
2334 LLVM_DEBUG(
dbgs() <<
"Set inline attribute to function: " <<
F->getName()
2337 for (
auto &
F : ColdFunctions) {
2340 if (
F->hasFnAttribute(Attribute::Hot)) {
2341 auto &Ctx = M.getContext();
2342 std::string Msg = std::string(
"Function ") +
F->getName().str() +
2343 std::string(
" is annotated as a hot function but"
2344 " the profile is cold");
2349 F->addFnAttr(Attribute::Cold);
2350 LLVM_DEBUG(
dbgs() <<
"Set cold attribute to function: " <<
F->getName()
2357 std::string
Filename, std::string RemappingFilename,
bool IsCS,
2360 ProfileRemappingFileName(
std::
move(RemappingFilename)), IsCS(IsCS),
2389 LookupTLI, LookupBPI, LookupBFI, LookupLI, PSI,
2397 if (!
Node->getName().empty())
2398 return Node->getName().str();
2400 std::string SimpleNodeName;
2403 return SimpleNodeName;
2420 if (BrCondStr.empty())
2424 std::accumulate(Weights.begin(), Weights.end(), (
uint64_t)0,
2432 std::string BranchProbStr;
2435 OS <<
" (total count : " << TotalCount <<
")";
2440 << BrCondStr <<
" is true with probability : " << BranchProbStr;
2459 return &
G->getFunc().front();
2482 return std::string(
G->getFunc().getName());
2490 PGOUseBBInfo *BI = Graph->findBBInfo(
Node);
2492 if (BI && BI->Count)
2493 OS << *BI->Count <<
"\\l";
2504 OS <<
"SELECT : { T = ";
2508 OS <<
"Unknown, F = Unknown }\\l";
2510 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")
#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 constexpr StringLiteral Filename
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")))
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> 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 const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
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....
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
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; assumes that the block is well-formed.
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI bool isIrrLoopHeader(const BasicBlock *BB)
Returns true if BB is an irreducible loop header block.
LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const BasicBlock *BB, bool AllowSynthetic=false) const
Returns the estimated profile count of BB.
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
Conditional Branch instruction.
Value * getCondition() 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.
@ 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.
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
constexpr const char * data() const
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 * > OverloadTys={})
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.
LLVM_ABI void checkExpectAnnotations(const Instruction &I, 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 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 bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr, DomTreeUpdater *DTU=nullptr)
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"))
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)
Instruction::const_succ_iterator const_succ_iterator
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."))
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.
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.
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)
static constexpr uint64_t FUNC_HASH_MASK
Instruction * AnnotatedInst