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 Triple TT(M.getTargetTriple());
474 if (TT.supportsCOMDAT()) {
476 IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName));
478 return IRLevelVersionVariable;
488enum VisitMode { VM_counting, VM_instrument, VM_annotate };
492struct SelectInstVisitor :
public InstVisitor<SelectInstVisitor> {
495 VisitMode Mode = VM_counting;
496 unsigned *CurCtrIdx =
nullptr;
497 unsigned TotalNumCtrs = 0;
498 GlobalValue *FuncNameVar =
nullptr;
499 uint64_t FuncHash = 0;
500 PGOUseFunc *UseFunc =
nullptr;
501 bool HasSingleByteCoverage;
503 SelectInstVisitor(Function &Func,
bool HasSingleByteCoverage)
504 : F(
Func), HasSingleByteCoverage(HasSingleByteCoverage) {}
506 void countSelects() {
516 void instrumentSelects(
unsigned *Ind,
unsigned TotalNC, GlobalValue *FNV,
518 Mode = VM_instrument;
520 TotalNumCtrs = TotalNC;
527 void annotateSelects(PGOUseFunc *UF,
unsigned *Ind) {
534 void instrumentOneSelectInst(SelectInst &SI);
535 void annotateOneSelectInst(SelectInst &SI);
538 void visitSelectInst(SelectInst &SI);
542 unsigned getNumOfSelectInsts()
const {
return NSIs; }
554 bool Removed =
false;
555 bool IsCritical =
false;
557 PGOEdge(BasicBlock *Src, BasicBlock *Dest, uint64_t W = 1)
558 : SrcBB(Src), DestBB(Dest), Weight(
W) {}
561 std::string infoString()
const {
562 return (Twine(Removed ?
"-" :
" ") + (InMST ?
" " :
"*") +
563 (IsCritical ?
"c" :
" ") +
" W=" + Twine(Weight))
574 PGOBBInfo(
unsigned IX) : Group(this), Index(IX) {}
577 std::string infoString()
const {
578 return (Twine(
"Index=") + Twine(Index)).str();
583template <
class Edge,
class BBInfo>
class FuncPGOInstrumentation {
591 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
593 ValueProfileCollector VPC;
595 void computeCFGHash();
596 void renameComdatFunction();
599 const TargetLibraryInfo &TLI;
600 std::vector<std::vector<VPCandidateInfo>> ValueSites;
601 SelectInstVisitor SIVisitor;
602 std::string FuncName;
603 std::string DeprecatedFuncName;
604 GlobalVariable *FuncNameVar;
607 uint64_t FunctionHash = 0;
610 CFGMST<Edge, BBInfo> MST;
612 const std::optional<BlockCoverageInference> BCI;
614 static std::optional<BlockCoverageInference>
615 constructBCI(Function &Func,
bool HasSingleByteCoverage,
616 bool InstrumentFuncEntry) {
617 if (HasSingleByteCoverage)
618 return BlockCoverageInference(Func, InstrumentFuncEntry);
624 void getInstrumentBBs(std::vector<BasicBlock *> &InstrumentBBs);
631 BBInfo &getBBInfo(
const BasicBlock *BB)
const {
return MST.getBBInfo(BB); }
634 BBInfo *findBBInfo(
const BasicBlock *BB)
const {
return MST.findBBInfo(BB); }
637 void dumpInfo(StringRef Str =
"")
const {
638 MST.dumpEdges(
dbgs(), Twine(
"Dump Function ") + FuncName +
639 " Hash: " + Twine(FunctionHash) +
"\t" + Str);
642 FuncPGOInstrumentation(
643 Function &Func, TargetLibraryInfo &TLI,
644 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
645 bool CreateGlobalVar =
false, BranchProbabilityInfo *BPI =
nullptr,
646 BlockFrequencyInfo *BFI =
nullptr, LoopInfo *LI =
nullptr,
647 bool IsCS =
false,
bool InstrumentFuncEntry =
true,
648 bool InstrumentLoopEntries =
false,
bool HasSingleByteCoverage =
false)
649 : F(
Func), IsCS(IsCS), ComdatMembers(ComdatMembers), VPC(
Func, TLI),
650 TLI(TLI), ValueSites(IPVK_Last + 1),
651 SIVisitor(
Func, HasSingleByteCoverage),
652 MST(F, InstrumentFuncEntry, InstrumentLoopEntries, BPI, BFI, LI),
653 BCI(constructBCI(
Func, HasSingleByteCoverage, InstrumentFuncEntry)) {
655 BCI->viewBlockCoverageGraph();
657 SIVisitor.countSelects();
658 ValueSites[IPVK_MemOPSize] = VPC.get(IPVK_MemOPSize);
660 NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
661 NumOfPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
662 NumOfPGOBB += MST.bbInfoSize();
663 ValueSites[IPVK_IndirectCallTarget] = VPC.get(IPVK_IndirectCallTarget);
665 ValueSites[IPVK_VTableTarget] = VPC.get(IPVK_VTableTarget);
667 NumOfCSPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
668 NumOfCSPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
669 NumOfCSPGOBB += MST.bbInfoSize();
675 if (!ComdatMembers.empty())
676 renameComdatFunction();
679 for (
const auto &
E : MST.allEdges()) {
682 IsCS ? NumOfCSPGOEdge++ : NumOfPGOEdge++;
684 IsCS ? NumOfCSPGOInstrument++ : NumOfPGOInstrument++;
697template <
class Edge,
class BBInfo>
698void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
699 std::vector<uint8_t> Indexes;
703 auto BI = findBBInfo(Succ);
707 for (
int J = 0; J < 4; J++)
708 Indexes.push_back((
uint8_t)(Index >> (J * 8)));
715 auto updateJCH = [&JCH](
uint64_t Num) {
720 updateJCH((
uint64_t)SIVisitor.getNumOfSelectInsts());
721 updateJCH((
uint64_t)ValueSites[IPVK_IndirectCallTarget].
size());
724 updateJCH(BCI->getInstrumentedBlocksHash());
737 LLVM_DEBUG(
dbgs() <<
"Function Hash Computation for " <<
F.getName() <<
":\n"
738 <<
" CRC = " << JC.
getCRC()
739 <<
", Selects = " << SIVisitor.getNumOfSelectInsts()
740 <<
", Edges = " << MST.
numEdges() <<
", ICSites = "
741 << ValueSites[IPVK_IndirectCallTarget].size()
742 <<
", Memops = " << ValueSites[IPVK_MemOPSize].size()
743 <<
", High32 CRC = " << JCH.
getCRC()
744 <<
", Hash = " << FunctionHash <<
"\n";);
747 dbgs() <<
"Funcname=" <<
F.getName() <<
", Hash=" << FunctionHash
748 <<
" in building " <<
F.getParent()->getSourceFileName() <<
"\n";
754 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
766 for (
auto &&CM :
make_range(ComdatMembers.equal_range(
C))) {
776template <
class Edge,
class BBInfo>
777void FuncPGOInstrumentation<Edge, BBInfo>::renameComdatFunction() {
780 std::string OrigName =
F.getName().str();
781 std::string NewFuncName =
783 F.setName(
Twine(NewFuncName));
785 FuncName =
Twine(FuncName +
"." +
Twine(FunctionHash)).
str();
791 if (!
F.hasComdat()) {
793 NewComdat = M->getOrInsertComdat(
StringRef(NewFuncName));
795 F.setComdat(NewComdat);
800 Comdat *OrigComdat =
F.getComdat();
801 std::string NewComdatName =
803 NewComdat = M->getOrInsertComdat(
StringRef(NewComdatName));
806 for (
auto &&CM :
make_range(ComdatMembers.equal_range(OrigComdat))) {
814template <
class Edge,
class BBInfo>
815void FuncPGOInstrumentation<Edge, BBInfo>::getInstrumentBBs(
816 std::vector<BasicBlock *> &InstrumentBBs) {
819 if (BCI->shouldInstrumentBlock(BB))
820 InstrumentBBs.push_back(&BB);
825 std::vector<Edge *> EdgeList;
828 EdgeList.push_back(
E.get());
830 for (
auto &
E : EdgeList) {
833 InstrumentBBs.push_back(InstrBB);
839template <
class Edge,
class BBInfo>
840BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *
E) {
841 if (
E->InMST ||
E->Removed)
847 if (SrcBB ==
nullptr)
849 if (DestBB ==
nullptr)
864 return canInstrument(SrcBB);
866 return canInstrument(DestBB);
875 dbgs() <<
"Fail to split critical edge: not instrument this edge.\n");
880 IsCS ? NumOfCSPGOSplit++ : NumOfPGOSplit++;
881 LLVM_DEBUG(
dbgs() <<
"Split critical edge: " << getBBInfo(SrcBB).Index
882 <<
" --> " << getBBInfo(DestBB).Index <<
"\n");
884 MST.
addEdge(SrcBB, InstrBB, 0);
886 Edge &NewEdge1 = MST.
addEdge(InstrBB, DestBB, 0);
887 NewEdge1.InMST =
true;
890 return canInstrument(InstrBB);
909 std::optional<OperandBundleUse> ParentFunclet =
917 if (!BlockColors.
empty()) {
918 const ColorVector &CV = BlockColors.
find(OrigCall->getParent())->second;
919 assert(CV.
size() == 1 &&
"non-unique color for block!");
921 if (EHPadIt->isEHPad())
929void FunctionInstrumenter::instrument() {
936 const bool IsCtxProf = InstrumentationType == PGOInstrumentationType::CTXPROF;
937 FuncPGOInstrumentation<PGOEdge, PGOBBInfo> FuncInfo(
938 F, TLI, ComdatMembers, !IsCtxProf, BPI, BFI, LI,
939 InstrumentationType == PGOInstrumentationType::CSFDO,
940 shouldInstrumentEntryBB(), shouldInstrumentLoopEntries(),
944 auto *
const CFGHash =
945 ConstantInt::get(Type::getInt64Ty(
M.getContext()), FuncInfo.FunctionHash);
949 Name, PointerType::get(
M.getContext(), 0));
951 auto &EntryBB =
F.getEntryBlock();
952 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstNonPHIOrDbgOrAlloca());
955 Builder.CreateIntrinsic(
956 Intrinsic::instrprof_cover,
957 {NormalizedNamePtr, CFGHash, Builder.getInt32(1), Builder.getInt32(0)});
961 std::vector<BasicBlock *> InstrumentBBs;
962 FuncInfo.getInstrumentBBs(InstrumentBBs);
964 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
979 auto Visit = [&](llvm::function_ref<void(CallBase * CB)> Visitor) {
981 for (
auto &Instr : BB)
985 if (CS->getCalledFunction() &&
986 SkipCSInstr.contains(CS->getCalledFunction()->getName()))
992 uint32_t TotalNumCallsites = 0;
993 Visit([&TotalNumCallsites](
auto *) { ++TotalNumCallsites; });
997 Visit([&](
auto *CB) {
999 Builder.CreateCall(CSIntrinsic,
1000 {
Name, CFGHash, Builder.getInt32(TotalNumCallsites),
1002 CB->getCalledOperand()});
1009 auto &EntryBB =
F.getEntryBlock();
1010 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstNonPHIOrDbgOrAlloca());
1013 Builder.CreateIntrinsic(Intrinsic::instrprof_timestamp,
1014 {NormalizedNamePtr, CFGHash,
1016 Builder.getInt32(
I)});
1020 for (
auto *InstrBB : InstrumentBBs) {
1022 assert(Builder.GetInsertPoint() != InstrBB->
end() &&
1023 "Cannot get the Instrumentation point");
1027 : Intrinsic::instrprof_increment,
1028 {NormalizedNamePtr, CFGHash,
1030 Builder.getInt32(
I++)});
1034 FuncInfo.SIVisitor.instrumentSelects(&
I,
NumCounters, Name,
1035 FuncInfo.FunctionHash);
1038 if (isValueProfilingDisabled())
1041 NumOfPGOICall += FuncInfo.ValueSites[IPVK_IndirectCallTarget].size();
1047 DenseMap<BasicBlock *, ColorVector> BlockColors;
1048 if (
F.hasPersonalityFn() &&
1053 for (uint32_t Kind = IPVK_First;
Kind <= IPVK_Last; ++
Kind) {
1054 unsigned SiteIndex = 0;
1060 <<
" site: CallSite Index = " << SiteIndex <<
"\n");
1063 assert(Builder.GetInsertPoint() != Cand.InsertPt->getParent()->end() &&
1064 "Cannot get the Instrumentation point");
1066 Value *ToProfile =
nullptr;
1067 if (Cand.V->getType()->isIntegerTy())
1068 ToProfile = Builder.CreateZExtOrTrunc(Cand.V, Builder.getInt64Ty());
1069 else if (Cand.V->getType()->isPointerTy())
1070 ToProfile = Builder.CreatePtrToInt(Cand.V, Builder.getInt64Ty());
1071 assert(ToProfile &&
"value profiling Value is of unexpected type");
1074 Name, PointerType::get(
M.getContext(), 0));
1080 Intrinsic::instrprof_value_profile),
1081 {NormalizedNamePtr, Builder.getInt64(FuncInfo.FunctionHash),
1082 ToProfile, Builder.getInt32(Kind), Builder.getInt32(SiteIndex++)},
1091struct PGOUseEdge :
public PGOEdge {
1092 using PGOEdge::PGOEdge;
1094 std::optional<uint64_t>
Count;
1100 std::string infoString()
const {
1102 return PGOEdge::infoString();
1103 return (Twine(PGOEdge::infoString()) +
" Count=" + Twine(*
Count)).str();
1110struct PGOUseBBInfo :
public PGOBBInfo {
1111 std::optional<uint64_t>
Count;
1112 int32_t UnknownCountInEdge = 0;
1113 int32_t UnknownCountOutEdge = 0;
1114 DirectEdges InEdges;
1115 DirectEdges OutEdges;
1117 PGOUseBBInfo(
unsigned IX) : PGOBBInfo(IX) {}
1123 std::string infoString()
const {
1125 return PGOBBInfo::infoString();
1126 return (Twine(PGOBBInfo::infoString()) +
" Count=" + Twine(*
Count)).str();
1130 void addOutEdge(PGOUseEdge *
E) {
1131 OutEdges.push_back(
E);
1132 UnknownCountOutEdge++;
1136 void addInEdge(PGOUseEdge *
E) {
1137 InEdges.push_back(
E);
1138 UnknownCountInEdge++;
1147 for (
const auto &
E : Edges) {
1160 PGOUseFunc(Function &Func,
Module *Modu, TargetLibraryInfo &TLI,
1161 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
1162 BranchProbabilityInfo *BPI, BlockFrequencyInfo *BFIin,
1163 LoopInfo *LI, ProfileSummaryInfo *PSI,
bool IsCS,
1164 bool InstrumentFuncEntry,
bool InstrumentLoopEntries,
1165 bool HasSingleByteCoverage)
1166 :
F(
Func),
M(Modu), BFI(BFIin), PSI(PSI),
1167 FuncInfo(
Func, TLI, ComdatMembers,
false, BPI, BFIin, LI, IsCS,
1168 InstrumentFuncEntry, InstrumentLoopEntries,
1169 HasSingleByteCoverage),
1170 FreqAttr(FFA_Normal), IsCS(IsCS), VPC(
Func, TLI) {}
1172 void handleInstrProfError(
Error Err, uint64_t MismatchedFuncSum);
1177 bool getRecord(IndexedInstrProfReader *PGOReader);
1180 bool readCounters(
bool &AllZeros,
1184 void populateCounters();
1187 void populateCoverage();
1193 void annotateValueSites();
1196 void annotateValueSites(uint32_t Kind);
1199 void annotateIrrLoopHeaderWeights();
1202 enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };
1205 FuncFreqAttr getFuncFreqAttr()
const {
return FreqAttr; }
1208 uint64_t
getFuncHash()
const {
return FuncInfo.FunctionHash; }
1211 NamedInstrProfRecord &getProfileRecord() {
return ProfileRecord; }
1214 PGOUseBBInfo &getBBInfo(
const BasicBlock *BB)
const {
1215 return FuncInfo.getBBInfo(BB);
1219 PGOUseBBInfo *findBBInfo(
const BasicBlock *BB)
const {
1220 return FuncInfo.findBBInfo(BB);
1225 void dumpInfo(StringRef Str =
"")
const { FuncInfo.dumpInfo(Str); }
1227 uint64_t getProgramMaxCount()
const {
return ProgramMaxCount; }
1232 BlockFrequencyInfo *BFI;
1233 ProfileSummaryInfo *PSI;
1236 FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> FuncInfo;
1240 uint64_t ProgramMaxCount;
1243 uint32_t CountPosition = 0;
1246 uint32_t ProfileCountSize = 0;
1249 NamedInstrProfRecord ProfileRecord;
1252 FuncFreqAttr FreqAttr;
1257 ValueProfileCollector VPC;
1260 bool setInstrumentedCounts(
const std::vector<uint64_t> &CountFromProfile);
1264 void setEdgeCount(DirectEdges &Edges, uint64_t
Value);
1269 void markFunctionAttributes(uint64_t EntryCount, uint64_t MaxCount) {
1273 FreqAttr = FFA_Cold;
1281 const FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> &FuncInfo) {
1285 for (
const auto &
E : FuncInfo.MST.allEdges()) {
1290 PGOUseBBInfo &SrcInfo = FuncInfo.getBBInfo(SrcBB);
1291 PGOUseBBInfo &DestInfo = FuncInfo.getBBInfo(DestBB);
1292 SrcInfo.addOutEdge(
E.get());
1293 DestInfo.addInEdge(
E.get());
1299bool PGOUseFunc::setInstrumentedCounts(
1300 const std::vector<uint64_t> &CountFromProfile) {
1302 std::vector<BasicBlock *> InstrumentBBs;
1303 FuncInfo.getInstrumentBBs(InstrumentBBs);
1308 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
1314 auto *FuncEntry = &*
F.begin();
1318 for (BasicBlock *InstrBB : InstrumentBBs) {
1319 uint64_t CountValue = CountFromProfile[
I++];
1320 PGOUseBBInfo &
Info = getBBInfo(InstrBB);
1324 if (InstrBB == FuncEntry && CountValue == 0)
1326 Info.setBBInfoCount(CountValue);
1328 ProfileCountSize = CountFromProfile.size();
1332 auto setEdgeCount = [
this](PGOUseEdge *
E, uint64_t
Value) ->
void {
1334 this->getBBInfo(
E->SrcBB).UnknownCountOutEdge--;
1335 this->getBBInfo(
E->DestBB).UnknownCountInEdge--;
1341 for (
const auto &
E : FuncInfo.MST.allEdges()) {
1342 if (
E->Removed ||
E->InMST)
1345 PGOUseBBInfo &SrcInfo = getBBInfo(SrcBB);
1349 if (SrcInfo.Count && SrcInfo.OutEdges.size() == 1)
1350 setEdgeCount(
E.get(), *SrcInfo.Count);
1353 PGOUseBBInfo &DestInfo = getBBInfo(DestBB);
1356 if (DestInfo.Count && DestInfo.InEdges.size() == 1)
1357 setEdgeCount(
E.get(), *DestInfo.Count);
1363 setEdgeCount(
E.get(), 0);
1370void PGOUseFunc::setEdgeCount(DirectEdges &Edges, uint64_t
Value) {
1371 for (
auto &
E : Edges) {
1376 getBBInfo(
E->SrcBB).UnknownCountOutEdge--;
1377 getBBInfo(
E->DestBB).UnknownCountInEdge--;
1385 const char MetadataName[] =
"instr_prof_hash_mismatch";
1388 auto *Existing =
F.getMetadata(LLVMContext::MD_annotation);
1391 for (
const auto &
N : Tuple->operands()) {
1392 if (
N.equalsStr(MetadataName))
1401 F.setMetadata(LLVMContext::MD_annotation, MD);
1404void PGOUseFunc::handleInstrProfError(
Error Err, uint64_t MismatchedFuncSum) {
1406 auto &Ctx =
M->getContext();
1407 auto Err = IPE.
get();
1408 bool SkipWarning =
false;
1410 << FuncInfo.FuncName <<
": ");
1411 if (Err == instrprof_error::unknown_function) {
1412 IsCS ? NumOfCSPGOMissing++ : NumOfPGOMissing++;
1415 }
else if (Err == instrprof_error::hash_mismatch ||
1416 Err == instrprof_error::malformed) {
1417 IsCS ? NumOfCSPGOMismatch++ : NumOfPGOMismatch++;
1423 LLVM_DEBUG(
dbgs() <<
"hash mismatch (hash= " << FuncInfo.FunctionHash
1424 <<
" skip=" << SkipWarning <<
")");
1434 IPE.
message() + std::string(
" ") +
F.getName().str() +
1435 std::string(
" Hash = ") + std::to_string(FuncInfo.FunctionHash) +
1436 std::string(
" up to ") + std::to_string(MismatchedFuncSum) +
1437 std::string(
" count discarded");
1440 DiagnosticInfoPGOProfile(
M->getName().data(), Msg,
DS_Warning));
1444bool PGOUseFunc::getRecord(IndexedInstrProfReader *PGOReader) {
1445 uint64_t MismatchedFuncSum = 0;
1447 FuncInfo.FuncName, FuncInfo.FunctionHash, FuncInfo.DeprecatedFuncName,
1448 &MismatchedFuncSum);
1450 handleInstrProfError(std::move(
E), MismatchedFuncSum);
1453 ProfileRecord = std::move(
Result.get());
1461bool PGOUseFunc::readCounters(
bool &AllZeros,
1463 auto &Ctx =
M->getContext();
1468 std::vector<uint64_t> &CountFromProfile = ProfileRecord.
Counts;
1470 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1473 uint64_t ValueSum = 0;
1474 for (
unsigned I = 0, S = CountFromProfile.size();
I < S;
I++) {
1476 ValueSum += CountFromProfile[
I];
1478 AllZeros = (ValueSum == 0);
1482 getBBInfo(
nullptr).UnknownCountOutEdge = 2;
1483 getBBInfo(
nullptr).UnknownCountInEdge = 2;
1485 if (!setInstrumentedCounts(CountFromProfile)) {
1487 dbgs() <<
"Inconsistent number of counts, skipping this function");
1488 Ctx.diagnose(DiagnosticInfoPGOProfile(
1489 M->getName().data(),
1490 Twine(
"Inconsistent number of counts in ") +
F.getName().str() +
1491 Twine(
": the profile may be stale or there is a function name "
1499void PGOUseFunc::populateCoverage() {
1500 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1502 ArrayRef<uint64_t> CountsFromProfile = ProfileRecord.
Counts;
1503 DenseMap<const BasicBlock *, bool>
Coverage;
1506 if (FuncInfo.BCI->shouldInstrumentBlock(BB))
1511 DenseMap<const BasicBlock *, DenseSet<const BasicBlock *>>
1512 InverseDependencies;
1513 for (
auto &BB :
F) {
1514 for (
auto *Dep : FuncInfo.BCI->getDependencies(BB)) {
1516 InverseDependencies[Dep].
insert(&BB);
1521 std::stack<const BasicBlock *> CoveredBlocksToProcess;
1522 for (
auto &[BB, IsCovered] : Coverage)
1524 CoveredBlocksToProcess.push(BB);
1526 while (!CoveredBlocksToProcess.empty()) {
1527 auto *CoveredBlock = CoveredBlocksToProcess.top();
1528 assert(Coverage[CoveredBlock]);
1529 CoveredBlocksToProcess.pop();
1530 for (
auto *BB : InverseDependencies[CoveredBlock]) {
1536 CoveredBlocksToProcess.push(BB);
1541 MDBuilder MDB(
F.getContext());
1544 F.setEntryCount(Coverage[&
F.getEntryBlock()] ? 10000 : 0);
1545 for (
auto &BB :
F) {
1552 SmallVector<uint32_t, 4> Weights;
1554 Weights.
push_back((Coverage[Succ] || !Coverage[&BB]) ? 1 : 0);
1555 if (Weights.
size() >= 2)
1560 unsigned NumCorruptCoverage = 0;
1561 DominatorTree DT(
F);
1563 BranchProbabilityInfo BPI(
F, LI);
1564 BlockFrequencyInfo BFI(
F, BPI, LI);
1565 auto IsBlockDead = [&](
const BasicBlock &BB) -> std::optional<bool> {
1570 LLVM_DEBUG(
dbgs() <<
"Block Coverage: (Instrumented=*, Covered=X)\n");
1571 for (
auto &BB :
F) {
1572 LLVM_DEBUG(
dbgs() << (FuncInfo.BCI->shouldInstrumentBlock(BB) ?
"* " :
" ")
1573 << (Coverage[&BB] ?
"X " :
" ") <<
" " << BB.getName()
1580 if (Cov == IsBlockDead(BB).value_or(
false)) {
1582 dbgs() <<
"Found inconsistent block covearge for " << BB.getName()
1583 <<
": BCI=" << (Cov ?
"Covered" :
"Dead") <<
" BFI="
1584 << (IsBlockDead(BB).value() ?
"Dead" :
"Covered") <<
"\n");
1585 ++NumCorruptCoverage;
1591 auto &Ctx =
M->getContext();
1592 Ctx.diagnose(DiagnosticInfoPGOProfile(
1593 M->getName().data(),
1594 Twine(
"Found inconsistent block coverage for function ") +
F.getName() +
1595 " in " + Twine(NumCorruptCoverage) +
" blocks.",
1599 FuncInfo.BCI->viewBlockCoverageGraph(&Coverage);
1604void PGOUseFunc::populateCounters() {
1605 bool Changes =
true;
1606 unsigned NumPasses = 0;
1614 PGOUseBBInfo *UseBBInfo = findBBInfo(&BB);
1615 if (UseBBInfo ==
nullptr)
1617 if (!UseBBInfo->Count) {
1618 if (UseBBInfo->UnknownCountOutEdge == 0) {
1621 }
else if (UseBBInfo->UnknownCountInEdge == 0) {
1626 if (UseBBInfo->Count) {
1627 if (UseBBInfo->UnknownCountOutEdge == 1) {
1633 if (*UseBBInfo->Count > OutSum)
1634 Total = *UseBBInfo->Count - OutSum;
1635 setEdgeCount(UseBBInfo->OutEdges,
Total);
1638 if (UseBBInfo->UnknownCountInEdge == 1) {
1641 if (*UseBBInfo->Count > InSum)
1642 Total = *UseBBInfo->Count - InSum;
1643 setEdgeCount(UseBBInfo->InEdges,
Total);
1650 LLVM_DEBUG(
dbgs() <<
"Populate counts in " << NumPasses <<
" passes.\n");
1654 for (
auto &BB :
F) {
1655 auto BI = findBBInfo(&BB);
1658 assert(BI->Count &&
"BB count is not valid");
1662 FuncInfo.SIVisitor.annotateSelects(
this, &CountPosition);
1663 assert(CountPosition == ProfileCountSize);
1667 for (
auto &BB :
F) {
1668 auto BI = findBBInfo(&BB);
1671 FuncMaxCount = std::max(FuncMaxCount, *BI->Count);
1680 LLVM_DEBUG(FuncInfo.dumpInfo(
"after reading profile."));
1684void PGOUseFunc::setBranchWeights() {
1686 LLVM_DEBUG(
dbgs() <<
"\nSetting branch weights for func " <<
F.getName()
1687 <<
" IsCS=" << IsCS <<
"\n");
1688 for (
auto &BB :
F) {
1697 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1698 if (!*BBCountInfo.Count)
1705 unsigned OutEdgesCount = BBCountInfo.OutEdges.size();
1706 unsigned SuccessorCount = BB.getTerminator()->getNumSuccessors();
1707 assert(OutEdgesCount <= SuccessorCount);
1710 uint64_t MaxCount = 0;
1711 for (
unsigned It = 0; It < OutEdgesCount; It++) {
1712 const PGOUseEdge *
E = BBCountInfo.OutEdges[It];
1715 if (DestBB ==
nullptr)
1718 uint64_t EdgeCount = *
E->Count;
1719 if (EdgeCount > MaxCount)
1720 MaxCount = EdgeCount;
1721 EdgeCounts[SuccNum] = EdgeCount;
1730 auto &Ctx =
M->getContext();
1731 Ctx.diagnose(DiagnosticInfoPGOProfile(
1732 M->getName().data(),
1733 Twine(
"Profile in ") +
F.getName().str() +
1734 Twine(
" partially ignored") +
1735 Twine(
", possibly due to the lack of a return path."),
1749void PGOUseFunc::annotateIrrLoopHeaderWeights() {
1750 LLVM_DEBUG(
dbgs() <<
"\nAnnotating irreducible loop header weights.\n");
1752 for (
auto &BB :
F) {
1758 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1764void SelectInstVisitor::instrumentOneSelectInst(SelectInst &SI) {
1767 Type *Int64Ty = Builder.getInt64Ty();
1768 auto *Step = Builder.CreateZExt(
SI.getCondition(), Int64Ty);
1769 auto *NormalizedFuncNameVarPtr =
1771 FuncNameVar, PointerType::get(
M->getContext(), 0));
1772 Builder.CreateIntrinsic(Intrinsic::instrprof_increment_step,
1773 {NormalizedFuncNameVarPtr, Builder.getInt64(
FuncHash),
1774 Builder.getInt32(TotalNumCtrs),
1775 Builder.getInt32(*CurCtrIdx), Step});
1779void SelectInstVisitor::annotateOneSelectInst(SelectInst &SI) {
1780 std::vector<uint64_t> &CountFromProfile = UseFunc->getProfileRecord().Counts;
1781 assert(*CurCtrIdx < CountFromProfile.size() &&
1782 "Out of bound access of counters");
1783 uint64_t SCounts[2];
1784 SCounts[0] = CountFromProfile[*CurCtrIdx];
1786 uint64_t TotalCount = 0;
1787 auto BI = UseFunc->findBBInfo(
SI.getParent());
1788 if (BI !=
nullptr) {
1789 TotalCount = *BI->Count;
1792 if (TotalCount < SCounts[0])
1793 BI->Count = SCounts[0];
1796 SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);
1797 uint64_t MaxCount = std::max(SCounts[0], SCounts[1]);
1802void SelectInstVisitor::visitSelectInst(SelectInst &SI) {
1806 if (
SI.getCondition()->getType()->isVectorTy())
1814 instrumentOneSelectInst(SI);
1817 annotateOneSelectInst(SI);
1825 if (ValueProfKind == IPVK_MemOPSize)
1827 if (ValueProfKind == llvm::IPVK_VTableTarget)
1833void PGOUseFunc::annotateValueSites() {
1840 for (uint32_t Kind = IPVK_First;
Kind <= IPVK_Last; ++
Kind)
1841 annotateValueSites(Kind);
1845void PGOUseFunc::annotateValueSites(uint32_t Kind) {
1846 assert(Kind <= IPVK_Last);
1847 unsigned ValueSiteIndex = 0;
1861 NumValueSites != FuncInfo.ValueSites[IPVK_VTableTarget].size() &&
1863 FuncInfo.ValueSites[IPVK_VTableTarget] = VPC.
get(IPVK_VTableTarget);
1864 auto &ValueSites = FuncInfo.ValueSites[
Kind];
1866 auto &Ctx =
M->getContext();
1867 Ctx.diagnose(DiagnosticInfoPGOProfile(
1868 M->getName().data(),
1869 Twine(
"Inconsistent number of value sites for ") +
1872 Twine(
"\", possibly due to the use of a stale profile."),
1878 LLVM_DEBUG(
dbgs() <<
"Read one value site profile (kind = " << Kind
1879 <<
"): Index = " << ValueSiteIndex <<
" out of "
1882 *M, *
I.AnnotatedInst, ProfileRecord,
1893 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
1898 ComdatMembers.insert(std::make_pair(
C, &
F));
1900 if (
Comdat *
C = GV.getComdat())
1901 ComdatMembers.insert(std::make_pair(
C, &GV));
1903 if (
Comdat *
C = GA.getComdat())
1904 ComdatMembers.insert(std::make_pair(
C, &GA));
1909 if (
F.isDeclaration())
1914 unsigned NumCriticalEdges = 0;
1915 for (
auto &BB :
F) {
1924 <<
", NumCriticalEdges=" << NumCriticalEdges
1925 <<
" exceed the threshold. Skip PGO.\n");
1935 if (
F.hasFnAttribute(llvm::Attribute::Naked))
1937 if (
F.hasFnAttribute(llvm::Attribute::NoProfile))
1939 if (
F.hasFnAttribute(llvm::Attribute::SkipProfile))
1944 if (
auto EntryCount =
F.getEntryCount())
1962 Triple TT(M.getTargetTriple());
1967 Twine(
"VTable value profiling is presently not "
1968 "supported for non-ELF object formats"),
1970 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
1980 FunctionInstrumenter FI(M,
F, TLI, ComdatMembers, BPI, BFI, LI,
1981 InstrumentationType);
1994 if (ProfileSampling)
2019 InstrumentationType))
2032 auto BFIEntryCount =
F.getEntryCount();
2033 assert(BFIEntryCount && (BFIEntryCount->getCount() > 0) &&
2034 "Invalid BFI Entrycount");
2038 for (
auto &BBI :
F) {
2041 if (!Func.findBBInfo(&BBI))
2044 CountValue = *Func.getBBInfo(&BBI).Count;
2045 BFICountValue = *BFICount;
2049 if (SumCount.isZero())
2053 "Incorrect sum of BFI counts");
2056 double Scale = (SumCount / SumBFICount).convertToDouble();
2057 if (Scale < 1.001 && Scale > 0.999)
2062 if (NewEntryCount == 0)
2068 << NewEntryCount <<
"\n");
2085 unsigned BBNum = 0, BBMisMatchNum = 0, NonZeroBBNum = 0;
2086 for (
auto &BBI :
F) {
2087 PGOUseBBInfo *BBInfo = Func.findBBInfo(&BBI);
2091 uint64_t CountValue = BBInfo->Count.value_or(CountValue);
2099 BFICountValue = *BFICount;
2102 bool rawIsHot = CountValue >= HotCountThreshold;
2103 bool BFIIsHot = BFICountValue >= HotCountThreshold;
2105 bool ShowCount =
false;
2106 if (rawIsHot && !BFIIsHot) {
2107 Msg =
"raw-Hot to BFI-nonHot";
2109 }
else if (rawIsCold && BFIIsHot) {
2110 Msg =
"raw-Cold to BFI-Hot";
2119 uint64_t Diff = (BFICountValue >= CountValue)
2120 ? BFICountValue - CountValue
2121 : CountValue - BFICountValue;
2129 F.getSubprogram(), &BBI);
2131 <<
" Count=" <<
ore::NV(
"Count", CountValue)
2132 <<
" BFI_Count=" <<
ore::NV(
"Count", BFICountValue);
2134 Remark <<
" (" << Msg <<
")";
2141 F.getSubprogram(), &
F.getEntryBlock())
2142 <<
"In Func " <<
ore::NV(
"Function",
F.getName())
2143 <<
": Num_of_BB=" <<
ore::NV(
"Count", BBNum)
2144 <<
", Num_of_non_zerovalue_BB=" <<
ore::NV(
"Count", NonZeroBBNum)
2145 <<
", Num_of_mis_matching_BB=" <<
ore::NV(
"Count", BBMisMatchNum);
2158 auto &Ctx = M.getContext();
2161 ProfileRemappingFileName);
2162 if (
Error E = ReaderOrErr.takeError()) {
2170 std::unique_ptr<IndexedInstrProfReader> PGOReader =
2171 std::move(ReaderOrErr.get());
2177 if (!PGOReader->hasCSIRLevelProfile() && IsCS)
2181 if (!PGOReader->isIRLevelProfile()) {
2183 ProfileFileName.
data(),
"Not an IR level instrumentation profile"));
2186 if (PGOReader->functionEntryOnly()) {
2188 ProfileFileName.
data(),
2189 "Function entry profiles are not yet supported for optimization"));
2195 if (!
G.hasName() || !
G.hasMetadata(LLVMContext::MD_type))
2206 M.setProfileSummary(PGOReader->getSummary(IsCS).getMD(M.getContext()),
2211 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
2213 std::vector<Function *> HotFunctions;
2214 std::vector<Function *> ColdFunctions;
2218 bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled();
2221 bool InstrumentLoopEntries = PGOReader->instrLoopEntriesEnabled();
2225 bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage();
2233 if (!HasSingleByteCoverage) {
2239 PGOUseFunc Func(
F, &M, TLI, ComdatMembers, BPI, BFI, LI, PSI, IsCS,
2240 InstrumentFuncEntry, InstrumentLoopEntries,
2241 HasSingleByteCoverage);
2242 if (!Func.getRecord(PGOReader.get()))
2244 if (HasSingleByteCoverage) {
2245 Func.populateCoverage();
2253 bool AllZeros =
false;
2254 if (!Func.readCounters(AllZeros, PseudoKind))
2258 if (Func.getProgramMaxCount() != 0)
2259 ColdFunctions.push_back(&
F);
2264 if (
F.hasFnAttribute(Attribute::Cold))
2265 F.removeFnAttr(Attribute::Cold);
2268 F.addFnAttr(Attribute::Hot);
2271 Func.populateCounters();
2272 Func.setBranchWeights();
2273 Func.annotateValueSites();
2274 Func.annotateIrrLoopHeaderWeights();
2275 PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();
2276 if (FreqAttr == PGOUseFunc::FFA_Cold)
2277 ColdFunctions.push_back(&
F);
2278 else if (FreqAttr == PGOUseFunc::FFA_Hot)
2279 HotFunctions.push_back(&
F);
2284 std::unique_ptr<BranchProbabilityInfo> NewBPI =
2285 std::make_unique<BranchProbabilityInfo>(
F, LI);
2286 std::unique_ptr<BlockFrequencyInfo> NewBFI =
2287 std::make_unique<BlockFrequencyInfo>(
F, *NewBPI, LI);
2291 dbgs() <<
"pgo-view-counts: " << Func.getFunc().getName() <<
"\n";
2292 NewBFI->print(
dbgs());
2302 ViewGraph(&Func,
Twine(
"PGORawCounts_") + Func.getFunc().getName());
2304 dbgs() <<
"pgo-view-raw-counts: " << Func.getFunc().getName() <<
"\n";
2331 for (
auto &
F : HotFunctions) {
2332 F->addFnAttr(Attribute::InlineHint);
2333 LLVM_DEBUG(
dbgs() <<
"Set inline attribute to function: " <<
F->getName()
2336 for (
auto &
F : ColdFunctions) {
2339 if (
F->hasFnAttribute(Attribute::Hot)) {
2340 auto &Ctx = M.getContext();
2341 std::string Msg = std::string(
"Function ") +
F->getName().str() +
2342 std::string(
" is annotated as a hot function but"
2343 " the profile is cold");
2348 F->addFnAttr(Attribute::Cold);
2349 LLVM_DEBUG(
dbgs() <<
"Set cold attribute to function: " <<
F->getName()
2356 std::string
Filename, std::string RemappingFilename,
bool IsCS,
2359 ProfileRemappingFileName(
std::
move(RemappingFilename)), IsCS(IsCS),
2388 LookupTLI, LookupBPI, LookupBFI, LookupLI, PSI,
2396 if (!
Node->getName().empty())
2397 return Node->getName().str();
2399 std::string SimpleNodeName;
2402 return SimpleNodeName;
2419 if (BrCondStr.empty())
2423 std::accumulate(Weights.begin(), Weights.end(), (
uint64_t)0,
2431 std::string BranchProbStr;
2434 OS <<
" (total count : " << TotalCount <<
")";
2439 << BrCondStr <<
" is true with probability : " << BranchProbStr;
2458 return &
G->getFunc().front();
2481 return std::string(
G->getFunc().getName());
2489 PGOUseBBInfo *BI = Graph->findBBInfo(
Node);
2491 if (BI && BI->Count)
2492 OS << *BI->Count <<
"\\l";
2503 OS <<
"SELECT : { T = ";
2507 OS <<
"Unknown, F = Unknown }\\l";
2509 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....
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; 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.
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(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