127#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 {
393 bool shouldInstrumentEntryBB()
const {
401 FunctionInstrumenter(
403 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
407 : M(M),
F(
F), TLI(TLI), ComdatMembers(ComdatMembers), BPI(BPI), BFI(BFI),
408 LI(LI), InstrumentationType(InstrumentationType) {}
419 return std::string();
424 return std::string();
436 else if (CV->
isOne())
447#define VALUE_PROF_KIND(Enumerator, Value, Descr) Descr,
480 Triple TT(M.getTargetTriple());
481 if (TT.supportsCOMDAT()) {
483 IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName));
485 return IRLevelVersionVariable;
495enum VisitMode { VM_counting, VM_instrument, VM_annotate };
499struct SelectInstVisitor :
public InstVisitor<SelectInstVisitor> {
502 VisitMode Mode = VM_counting;
503 unsigned *CurCtrIdx =
nullptr;
504 unsigned TotalNumCtrs = 0;
505 GlobalValue *FuncNameVar =
nullptr;
506 uint64_t FuncHash = 0;
507 PGOUseFunc *UseFunc =
nullptr;
508 bool HasSingleByteCoverage;
510 SelectInstVisitor(Function &Func,
bool HasSingleByteCoverage)
511 : F(
Func), HasSingleByteCoverage(HasSingleByteCoverage) {}
513 void countSelects() {
523 void instrumentSelects(
unsigned *Ind,
unsigned TotalNC, GlobalValue *FNV,
525 Mode = VM_instrument;
527 TotalNumCtrs = TotalNC;
534 void annotateSelects(PGOUseFunc *UF,
unsigned *Ind) {
541 void instrumentOneSelectInst(SelectInst &SI);
542 void annotateOneSelectInst(SelectInst &SI);
545 void visitSelectInst(SelectInst &SI);
549 unsigned getNumOfSelectInsts()
const {
return NSIs; }
561 bool Removed =
false;
562 bool IsCritical =
false;
564 PGOEdge(BasicBlock *Src, BasicBlock *Dest, uint64_t W = 1)
565 : SrcBB(Src), DestBB(Dest), Weight(
W) {}
568 std::string infoString()
const {
569 return (Twine(Removed ?
"-" :
" ") + (InMST ?
" " :
"*") +
570 (IsCritical ?
"c" :
" ") +
" W=" + Twine(Weight))
581 PGOBBInfo(
unsigned IX) : Group(this), Index(IX) {}
584 std::string infoString()
const {
585 return (Twine(
"Index=") + Twine(Index)).str();
590template <
class Edge,
class BBInfo>
class FuncPGOInstrumentation {
598 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
600 ValueProfileCollector VPC;
602 void computeCFGHash();
603 void renameComdatFunction();
606 const TargetLibraryInfo &TLI;
607 std::vector<std::vector<VPCandidateInfo>> ValueSites;
608 SelectInstVisitor SIVisitor;
609 std::string FuncName;
610 std::string DeprecatedFuncName;
611 GlobalVariable *FuncNameVar;
614 uint64_t FunctionHash = 0;
617 CFGMST<Edge, BBInfo> MST;
619 const std::optional<BlockCoverageInference> BCI;
621 static std::optional<BlockCoverageInference>
622 constructBCI(Function &Func,
bool HasSingleByteCoverage,
623 bool InstrumentFuncEntry) {
624 if (HasSingleByteCoverage)
625 return BlockCoverageInference(Func, InstrumentFuncEntry);
631 void getInstrumentBBs(std::vector<BasicBlock *> &InstrumentBBs);
638 BBInfo &getBBInfo(
const BasicBlock *BB)
const {
return MST.getBBInfo(BB); }
641 BBInfo *findBBInfo(
const BasicBlock *BB)
const {
return MST.findBBInfo(BB); }
644 void dumpInfo(StringRef Str =
"")
const {
645 MST.dumpEdges(
dbgs(), Twine(
"Dump Function ") + FuncName +
646 " Hash: " + Twine(FunctionHash) +
"\t" + Str);
649 FuncPGOInstrumentation(
650 Function &Func, TargetLibraryInfo &TLI,
651 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
652 bool CreateGlobalVar =
false, BranchProbabilityInfo *BPI =
nullptr,
653 BlockFrequencyInfo *BFI =
nullptr, LoopInfo *LI =
nullptr,
654 bool IsCS =
false,
bool InstrumentFuncEntry =
true,
655 bool InstrumentLoopEntries =
false,
bool HasSingleByteCoverage =
false)
656 : F(
Func), IsCS(IsCS), ComdatMembers(ComdatMembers), VPC(
Func, TLI),
657 TLI(TLI), ValueSites(IPVK_Last + 1),
658 SIVisitor(
Func, HasSingleByteCoverage),
659 MST(F, InstrumentFuncEntry, InstrumentLoopEntries, BPI, BFI, LI),
660 BCI(constructBCI(
Func, HasSingleByteCoverage, InstrumentFuncEntry)) {
662 BCI->viewBlockCoverageGraph();
664 SIVisitor.countSelects();
665 ValueSites[IPVK_MemOPSize] = VPC.get(IPVK_MemOPSize);
667 NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
668 NumOfPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
669 NumOfPGOBB += MST.bbInfoSize();
670 ValueSites[IPVK_IndirectCallTarget] = VPC.get(IPVK_IndirectCallTarget);
672 ValueSites[IPVK_VTableTarget] = VPC.get(IPVK_VTableTarget);
674 NumOfCSPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
675 NumOfCSPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
676 NumOfCSPGOBB += MST.bbInfoSize();
682 if (!ComdatMembers.empty())
683 renameComdatFunction();
686 for (
const auto &
E : MST.allEdges()) {
689 IsCS ? NumOfCSPGOEdge++ : NumOfPGOEdge++;
691 IsCS ? NumOfCSPGOInstrument++ : NumOfPGOInstrument++;
704template <
class Edge,
class BBInfo>
705void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
706 std::vector<uint8_t> Indexes;
710 auto BI = findBBInfo(Succ);
714 for (
int J = 0; J < 4; J++)
715 Indexes.push_back((
uint8_t)(Index >> (J * 8)));
722 auto updateJCH = [&JCH](
uint64_t Num) {
727 updateJCH((
uint64_t)SIVisitor.getNumOfSelectInsts());
728 updateJCH((
uint64_t)ValueSites[IPVK_IndirectCallTarget].
size());
731 updateJCH(BCI->getInstrumentedBlocksHash());
744 LLVM_DEBUG(
dbgs() <<
"Function Hash Computation for " <<
F.getName() <<
":\n"
745 <<
" CRC = " << JC.
getCRC()
746 <<
", Selects = " << SIVisitor.getNumOfSelectInsts()
747 <<
", Edges = " << MST.
numEdges() <<
", ICSites = "
748 << ValueSites[IPVK_IndirectCallTarget].size()
749 <<
", Memops = " << ValueSites[IPVK_MemOPSize].size()
750 <<
", High32 CRC = " << JCH.
getCRC()
751 <<
", Hash = " << FunctionHash <<
"\n";);
754 dbgs() <<
"Funcname=" <<
F.getName() <<
", Hash=" << FunctionHash
755 <<
" in building " <<
F.getParent()->getSourceFileName() <<
"\n";
761 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
773 for (
auto &&CM :
make_range(ComdatMembers.equal_range(
C))) {
783template <
class Edge,
class BBInfo>
784void FuncPGOInstrumentation<Edge, BBInfo>::renameComdatFunction() {
787 std::string OrigName =
F.getName().str();
788 std::string NewFuncName =
790 F.setName(
Twine(NewFuncName));
792 FuncName =
Twine(FuncName +
"." +
Twine(FunctionHash)).
str();
798 if (!
F.hasComdat()) {
800 NewComdat = M->getOrInsertComdat(
StringRef(NewFuncName));
802 F.setComdat(NewComdat);
807 Comdat *OrigComdat =
F.getComdat();
808 std::string NewComdatName =
810 NewComdat = M->getOrInsertComdat(
StringRef(NewComdatName));
813 for (
auto &&CM :
make_range(ComdatMembers.equal_range(OrigComdat))) {
821template <
class Edge,
class BBInfo>
822void FuncPGOInstrumentation<Edge, BBInfo>::getInstrumentBBs(
823 std::vector<BasicBlock *> &InstrumentBBs) {
826 if (BCI->shouldInstrumentBlock(BB))
827 InstrumentBBs.push_back(&BB);
832 std::vector<Edge *> EdgeList;
835 EdgeList.push_back(
E.get());
837 for (
auto &
E : EdgeList) {
840 InstrumentBBs.push_back(InstrBB);
846template <
class Edge,
class BBInfo>
847BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *
E) {
848 if (
E->InMST ||
E->Removed)
854 if (SrcBB ==
nullptr)
856 if (DestBB ==
nullptr)
871 return canInstrument(SrcBB);
873 return canInstrument(DestBB);
882 dbgs() <<
"Fail to split critical edge: not instrument this edge.\n");
887 IsCS ? NumOfCSPGOSplit++ : NumOfPGOSplit++;
888 LLVM_DEBUG(
dbgs() <<
"Split critical edge: " << getBBInfo(SrcBB).Index
889 <<
" --> " << getBBInfo(DestBB).Index <<
"\n");
891 MST.
addEdge(SrcBB, InstrBB, 0);
893 Edge &NewEdge1 = MST.
addEdge(InstrBB, DestBB, 0);
894 NewEdge1.InMST =
true;
897 return canInstrument(InstrBB);
916 std::optional<OperandBundleUse> ParentFunclet =
924 if (!BlockColors.
empty()) {
925 const ColorVector &CV = BlockColors.
find(OrigCall->getParent())->second;
926 assert(CV.
size() == 1 &&
"non-unique color for block!");
928 if (EHPadIt->isEHPad())
936void FunctionInstrumenter::instrument() {
943 const bool IsCtxProf = InstrumentationType == PGOInstrumentationType::CTXPROF;
944 FuncPGOInstrumentation<PGOEdge, PGOBBInfo> FuncInfo(
945 F, TLI, ComdatMembers, !IsCtxProf, BPI, BFI, LI,
946 InstrumentationType == PGOInstrumentationType::CSFDO,
947 shouldInstrumentEntryBB(), shouldInstrumentLoopEntries(),
951 auto *
const CFGHash =
952 ConstantInt::get(Type::getInt64Ty(
M.getContext()), FuncInfo.FunctionHash);
956 Name, PointerType::get(
M.getContext(), 0));
958 auto &EntryBB =
F.getEntryBlock();
959 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstNonPHIOrDbgOrAlloca());
962 Builder.CreateIntrinsic(
963 Intrinsic::instrprof_cover,
964 {NormalizedNamePtr, CFGHash, Builder.getInt32(1), Builder.getInt32(0)});
968 std::vector<BasicBlock *> InstrumentBBs;
969 FuncInfo.getInstrumentBBs(InstrumentBBs);
970 unsigned NumCounters =
971 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
986 auto Visit = [&](llvm::function_ref<void(CallBase * CB)> Visitor) {
988 for (
auto &Instr : BB)
992 if (CS->getCalledFunction() &&
993 SkipCSInstr.contains(CS->getCalledFunction()->getName()))
999 uint32_t TotalNumCallsites = 0;
1000 Visit([&TotalNumCallsites](
auto *) { ++TotalNumCallsites; });
1004 Visit([&](
auto *CB) {
1006 Builder.CreateCall(CSIntrinsic,
1007 {
Name, CFGHash, Builder.getInt32(TotalNumCallsites),
1009 CB->getCalledOperand()});
1016 auto &EntryBB =
F.getEntryBlock();
1017 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstNonPHIOrDbgOrAlloca());
1020 Builder.CreateIntrinsic(Intrinsic::instrprof_timestamp,
1021 {NormalizedNamePtr, CFGHash,
1022 Builder.getInt32(NumCounters),
1023 Builder.getInt32(
I)});
1027 for (
auto *InstrBB : InstrumentBBs) {
1029 assert(Builder.GetInsertPoint() != InstrBB->
end() &&
1030 "Cannot get the Instrumentation point");
1034 : Intrinsic::instrprof_increment,
1035 {NormalizedNamePtr, CFGHash,
1036 Builder.getInt32(NumCounters),
1037 Builder.getInt32(
I++)});
1041 FuncInfo.SIVisitor.instrumentSelects(&
I, NumCounters, Name,
1042 FuncInfo.FunctionHash);
1045 if (isValueProfilingDisabled())
1048 NumOfPGOICall += FuncInfo.ValueSites[IPVK_IndirectCallTarget].size();
1054 DenseMap<BasicBlock *, ColorVector> BlockColors;
1055 if (
F.hasPersonalityFn() &&
1060 for (uint32_t Kind = IPVK_First;
Kind <= IPVK_Last; ++
Kind) {
1061 unsigned SiteIndex = 0;
1067 <<
" site: CallSite Index = " << SiteIndex <<
"\n");
1070 assert(Builder.GetInsertPoint() != Cand.InsertPt->getParent()->end() &&
1071 "Cannot get the Instrumentation point");
1073 Value *ToProfile =
nullptr;
1074 if (Cand.V->getType()->isIntegerTy())
1075 ToProfile = Builder.CreateZExtOrTrunc(Cand.V, Builder.getInt64Ty());
1076 else if (Cand.V->getType()->isPointerTy())
1077 ToProfile = Builder.CreatePtrToInt(Cand.V, Builder.getInt64Ty());
1078 assert(ToProfile &&
"value profiling Value is of unexpected type");
1081 Name, PointerType::get(
M.getContext(), 0));
1087 Intrinsic::instrprof_value_profile),
1088 {NormalizedNamePtr, Builder.getInt64(FuncInfo.FunctionHash),
1089 ToProfile, Builder.getInt32(Kind), Builder.getInt32(SiteIndex++)},
1098struct PGOUseEdge :
public PGOEdge {
1099 using PGOEdge::PGOEdge;
1101 std::optional<uint64_t>
Count;
1107 std::string infoString()
const {
1109 return PGOEdge::infoString();
1110 return (Twine(PGOEdge::infoString()) +
" Count=" + Twine(*
Count)).str();
1117struct PGOUseBBInfo :
public PGOBBInfo {
1118 std::optional<uint64_t>
Count;
1119 int32_t UnknownCountInEdge = 0;
1120 int32_t UnknownCountOutEdge = 0;
1121 DirectEdges InEdges;
1122 DirectEdges OutEdges;
1124 PGOUseBBInfo(
unsigned IX) : PGOBBInfo(IX) {}
1130 std::string infoString()
const {
1132 return PGOBBInfo::infoString();
1133 return (Twine(PGOBBInfo::infoString()) +
" Count=" + Twine(*
Count)).str();
1137 void addOutEdge(PGOUseEdge *
E) {
1138 OutEdges.push_back(
E);
1139 UnknownCountOutEdge++;
1143 void addInEdge(PGOUseEdge *
E) {
1144 InEdges.push_back(
E);
1145 UnknownCountInEdge++;
1154 for (
const auto &
E : Edges) {
1167 PGOUseFunc(Function &Func,
Module *Modu, TargetLibraryInfo &TLI,
1168 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
1169 BranchProbabilityInfo *BPI, BlockFrequencyInfo *BFIin,
1170 LoopInfo *LI, ProfileSummaryInfo *PSI,
bool IsCS,
1171 bool InstrumentFuncEntry,
bool InstrumentLoopEntries,
1172 bool HasSingleByteCoverage)
1173 :
F(
Func),
M(Modu), BFI(BFIin), PSI(PSI),
1174 FuncInfo(
Func, TLI, ComdatMembers,
false, BPI, BFIin, LI, IsCS,
1175 InstrumentFuncEntry, InstrumentLoopEntries,
1176 HasSingleByteCoverage),
1177 FreqAttr(FFA_Normal), IsCS(IsCS), VPC(
Func, TLI) {}
1179 void handleInstrProfError(
Error Err, uint64_t MismatchedFuncSum);
1184 bool getRecord(IndexedInstrProfReader *PGOReader);
1187 bool readCounters(
bool &AllZeros,
1191 void populateCounters();
1194 void populateCoverage();
1200 void annotateValueSites();
1203 void annotateValueSites(uint32_t Kind);
1206 void annotateIrrLoopHeaderWeights();
1209 void setBlockUniformityAttribute();
1212 enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };
1215 FuncFreqAttr getFuncFreqAttr()
const {
return FreqAttr; }
1218 uint64_t
getFuncHash()
const {
return FuncInfo.FunctionHash; }
1221 NamedInstrProfRecord &getProfileRecord() {
return ProfileRecord; }
1224 PGOUseBBInfo &getBBInfo(
const BasicBlock *BB)
const {
1225 return FuncInfo.getBBInfo(BB);
1229 PGOUseBBInfo *findBBInfo(
const BasicBlock *BB)
const {
1230 return FuncInfo.findBBInfo(BB);
1235 void dumpInfo(StringRef Str =
"")
const { FuncInfo.dumpInfo(Str); }
1237 uint64_t getProgramMaxCount()
const {
return ProgramMaxCount; }
1242 BlockFrequencyInfo *BFI;
1243 ProfileSummaryInfo *PSI;
1246 FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> FuncInfo;
1250 uint64_t ProgramMaxCount;
1253 uint32_t CountPosition = 0;
1256 uint32_t ProfileCountSize = 0;
1259 NamedInstrProfRecord ProfileRecord;
1262 FuncFreqAttr FreqAttr;
1267 ValueProfileCollector VPC;
1270 bool setInstrumentedCounts(
const std::vector<uint64_t> &CountFromProfile);
1274 void setEdgeCount(DirectEdges &Edges, uint64_t
Value);
1279 void markFunctionAttributes(uint64_t EntryCount, uint64_t MaxCount) {
1283 FreqAttr = FFA_Cold;
1291 const FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> &FuncInfo) {
1295 for (
const auto &
E : FuncInfo.MST.allEdges()) {
1300 PGOUseBBInfo &SrcInfo = FuncInfo.getBBInfo(SrcBB);
1301 PGOUseBBInfo &DestInfo = FuncInfo.getBBInfo(DestBB);
1302 SrcInfo.addOutEdge(
E.get());
1303 DestInfo.addInEdge(
E.get());
1309bool PGOUseFunc::setInstrumentedCounts(
1310 const std::vector<uint64_t> &CountFromProfile) {
1312 std::vector<BasicBlock *> InstrumentBBs;
1313 FuncInfo.getInstrumentBBs(InstrumentBBs);
1317 unsigned NumInstrumentedBBs = InstrumentBBs.size();
1318 unsigned NumSelects = FuncInfo.SIVisitor.getNumOfSelectInsts();
1319 unsigned NumCounters = NumInstrumentedBBs + NumSelects;
1322 if (NumCounters != CountFromProfile.size()) {
1324 dbgs() <<
"PGO COUNTER MISMATCH for function " <<
F.getName() <<
":\n";
1325 dbgs() <<
" Expected counters: " << NumCounters <<
"\n";
1326 dbgs() <<
" - From instrumented edges: " << NumInstrumentedBBs <<
"\n";
1327 for (
size_t i = 0; i < InstrumentBBs.size(); ++i) {
1328 dbgs() <<
" " << i <<
": ";
1329 InstrumentBBs[i]->printAsOperand(
dbgs(),
false);
1332 dbgs() <<
" - From select instructions: " << NumSelects <<
"\n";
1333 dbgs() <<
" Actual counters from profile: " << CountFromProfile.size()
1338 auto *FuncEntry = &*
F.begin();
1342 for (BasicBlock *InstrBB : InstrumentBBs) {
1343 uint64_t CountValue = CountFromProfile[
I++];
1344 PGOUseBBInfo &
Info = getBBInfo(InstrBB);
1348 if (InstrBB == FuncEntry && CountValue == 0)
1350 Info.setBBInfoCount(CountValue);
1352 ProfileCountSize = CountFromProfile.size();
1356 auto setEdgeCount = [
this](PGOUseEdge *
E, uint64_t
Value) ->
void {
1358 this->getBBInfo(
E->SrcBB).UnknownCountOutEdge--;
1359 this->getBBInfo(
E->DestBB).UnknownCountInEdge--;
1365 for (
const auto &
E : FuncInfo.MST.allEdges()) {
1366 if (
E->Removed ||
E->InMST)
1369 PGOUseBBInfo &SrcInfo = getBBInfo(SrcBB);
1373 if (SrcInfo.Count && SrcInfo.OutEdges.size() == 1)
1374 setEdgeCount(
E.get(), *SrcInfo.Count);
1377 PGOUseBBInfo &DestInfo = getBBInfo(DestBB);
1380 if (DestInfo.Count && DestInfo.InEdges.size() == 1)
1381 setEdgeCount(
E.get(), *DestInfo.Count);
1387 setEdgeCount(
E.get(), 0);
1394void PGOUseFunc::setEdgeCount(DirectEdges &Edges, uint64_t
Value) {
1395 for (
auto &
E : Edges) {
1400 getBBInfo(
E->SrcBB).UnknownCountOutEdge--;
1401 getBBInfo(
E->DestBB).UnknownCountInEdge--;
1409 const char MetadataName[] =
"instr_prof_hash_mismatch";
1412 auto *Existing =
F.getMetadata(LLVMContext::MD_annotation);
1415 for (
const auto &
N : Tuple->operands()) {
1416 if (
N.equalsStr(MetadataName))
1425 F.setMetadata(LLVMContext::MD_annotation, MD);
1428void PGOUseFunc::handleInstrProfError(
Error Err, uint64_t MismatchedFuncSum) {
1430 auto &Ctx =
M->getContext();
1431 auto Err = IPE.
get();
1432 bool SkipWarning =
false;
1434 << FuncInfo.FuncName <<
": ");
1435 if (Err == instrprof_error::unknown_function) {
1436 IsCS ? NumOfCSPGOMissing++ : NumOfPGOMissing++;
1439 }
else if (Err == instrprof_error::hash_mismatch ||
1440 Err == instrprof_error::malformed) {
1441 IsCS ? NumOfCSPGOMismatch++ : NumOfPGOMismatch++;
1447 LLVM_DEBUG(
dbgs() <<
"hash mismatch (hash= " << FuncInfo.FunctionHash
1448 <<
" skip=" << SkipWarning <<
")");
1458 IPE.
message() + std::string(
" ") +
F.getName().str() +
1459 std::string(
" Hash = ") + std::to_string(FuncInfo.FunctionHash) +
1460 std::string(
" up to ") + std::to_string(MismatchedFuncSum) +
1461 std::string(
" count discarded");
1468bool PGOUseFunc::getRecord(IndexedInstrProfReader *PGOReader) {
1469 uint64_t MismatchedFuncSum = 0;
1471 FuncInfo.FuncName, FuncInfo.FunctionHash, FuncInfo.DeprecatedFuncName,
1472 &MismatchedFuncSum);
1474 handleInstrProfError(std::move(
E), MismatchedFuncSum);
1477 ProfileRecord = std::move(
Result.get());
1485bool PGOUseFunc::readCounters(
bool &AllZeros,
1487 auto &Ctx =
M->getContext();
1492 std::vector<uint64_t> &CountFromProfile = ProfileRecord.
Counts;
1494 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1497 uint64_t ValueSum = 0;
1498 for (
unsigned I = 0, S = CountFromProfile.size();
I < S;
I++) {
1500 ValueSum += CountFromProfile[
I];
1502 AllZeros = (ValueSum == 0);
1506 getBBInfo(
nullptr).UnknownCountOutEdge = 2;
1507 getBBInfo(
nullptr).UnknownCountInEdge = 2;
1509 if (!setInstrumentedCounts(CountFromProfile)) {
1511 dbgs() <<
"Inconsistent number of counts, skipping this function");
1512 Ctx.diagnose(DiagnosticInfoPGOProfile(
1513 M->getName().data(),
1514 Twine(
"Inconsistent number of counts in ") +
F.getName().str() +
1515 Twine(
": the profile may be stale or there is a function name "
1523void PGOUseFunc::populateCoverage() {
1524 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1526 ArrayRef<uint64_t> CountsFromProfile = ProfileRecord.
Counts;
1527 DenseMap<const BasicBlock *, bool>
Coverage;
1530 if (FuncInfo.BCI->shouldInstrumentBlock(BB))
1535 DenseMap<const BasicBlock *, DenseSet<const BasicBlock *>>
1536 InverseDependencies;
1537 for (
auto &BB :
F) {
1538 for (
auto *Dep : FuncInfo.BCI->getDependencies(BB)) {
1540 InverseDependencies[Dep].
insert(&BB);
1545 std::stack<const BasicBlock *> CoveredBlocksToProcess;
1546 for (
auto &[BB, IsCovered] : Coverage)
1548 CoveredBlocksToProcess.push(BB);
1550 while (!CoveredBlocksToProcess.empty()) {
1551 auto *CoveredBlock = CoveredBlocksToProcess.top();
1552 assert(Coverage[CoveredBlock]);
1553 CoveredBlocksToProcess.pop();
1554 for (
auto *BB : InverseDependencies[CoveredBlock]) {
1560 CoveredBlocksToProcess.push(BB);
1565 MDBuilder MDB(
F.getContext());
1568 F.setEntryCount(Coverage[&
F.getEntryBlock()] ? 10000 : 0);
1569 for (
auto &BB :
F) {
1576 SmallVector<uint32_t, 4> Weights;
1578 Weights.
push_back((Coverage[Succ] || !Coverage[&BB]) ? 1 : 0);
1579 if (Weights.
size() >= 2)
1584 unsigned NumCorruptCoverage = 0;
1585 DominatorTree DT(
F);
1589 BranchProbabilityInfo BPI(
F, CI);
1590 BlockFrequencyInfo BFI(
F, BPI, LI);
1591 auto IsBlockDead = [&](
const BasicBlock &BB) -> std::optional<bool> {
1596 LLVM_DEBUG(
dbgs() <<
"Block Coverage: (Instrumented=*, Covered=X)\n");
1597 for (
auto &BB :
F) {
1598 LLVM_DEBUG(
dbgs() << (FuncInfo.BCI->shouldInstrumentBlock(BB) ?
"* " :
" ")
1599 << (Coverage[&BB] ?
"X " :
" ") <<
" " << BB.getName()
1606 if (Cov == IsBlockDead(BB).value_or(
false)) {
1608 dbgs() <<
"Found inconsistent block covearge for " << BB.getName()
1609 <<
": BCI=" << (Cov ?
"Covered" :
"Dead") <<
" BFI="
1610 << (IsBlockDead(BB).value() ?
"Dead" :
"Covered") <<
"\n");
1611 ++NumCorruptCoverage;
1617 auto &Ctx =
M->getContext();
1618 Ctx.diagnose(DiagnosticInfoPGOProfile(
1619 M->getName().data(),
1620 Twine(
"Found inconsistent block coverage for function ") +
F.getName() +
1621 " in " + Twine(NumCorruptCoverage) +
" blocks.",
1625 FuncInfo.BCI->viewBlockCoverageGraph(&Coverage);
1630void PGOUseFunc::populateCounters() {
1631 bool Changes =
true;
1632 unsigned NumPasses = 0;
1640 PGOUseBBInfo *UseBBInfo = findBBInfo(&BB);
1641 if (UseBBInfo ==
nullptr)
1643 if (!UseBBInfo->Count) {
1644 if (UseBBInfo->UnknownCountOutEdge == 0) {
1647 }
else if (UseBBInfo->UnknownCountInEdge == 0) {
1652 if (UseBBInfo->Count) {
1653 if (UseBBInfo->UnknownCountOutEdge == 1) {
1659 if (*UseBBInfo->Count > OutSum)
1660 Total = *UseBBInfo->Count - OutSum;
1661 setEdgeCount(UseBBInfo->OutEdges,
Total);
1664 if (UseBBInfo->UnknownCountInEdge == 1) {
1667 if (*UseBBInfo->Count > InSum)
1668 Total = *UseBBInfo->Count - InSum;
1669 setEdgeCount(UseBBInfo->InEdges,
Total);
1676 LLVM_DEBUG(
dbgs() <<
"Populate counts in " << NumPasses <<
" passes.\n");
1680 for (
auto &BB :
F) {
1681 auto BI = findBBInfo(&BB);
1684 assert(BI->Count &&
"BB count is not valid");
1688 FuncInfo.SIVisitor.annotateSelects(
this, &CountPosition);
1689 assert(CountPosition == ProfileCountSize);
1693 for (
auto &BB :
F) {
1694 auto BI = findBBInfo(&BB);
1697 FuncMaxCount = std::max(FuncMaxCount, *BI->Count);
1706 LLVM_DEBUG(FuncInfo.dumpInfo(
"after reading profile."));
1710void PGOUseFunc::setBranchWeights() {
1712 LLVM_DEBUG(
dbgs() <<
"\nSetting branch weights for func " <<
F.getName()
1713 <<
" IsCS=" << IsCS <<
"\n");
1714 for (
auto &BB :
F) {
1723 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1724 if (!*BBCountInfo.Count)
1731 unsigned OutEdgesCount = BBCountInfo.OutEdges.size();
1732 unsigned SuccessorCount = BB.getTerminator()->getNumSuccessors();
1733 assert(OutEdgesCount <= SuccessorCount);
1736 uint64_t MaxCount = 0;
1737 for (
unsigned It = 0; It < OutEdgesCount; It++) {
1738 const PGOUseEdge *
E = BBCountInfo.OutEdges[It];
1741 if (DestBB ==
nullptr)
1744 uint64_t EdgeCount = *
E->Count;
1745 if (EdgeCount > MaxCount)
1746 MaxCount = EdgeCount;
1747 EdgeCounts[SuccNum] = EdgeCount;
1756 auto &Ctx =
M->getContext();
1757 Ctx.diagnose(DiagnosticInfoPGOProfile(
1758 M->getName().data(),
1759 Twine(
"Profile in ") +
F.getName().str() +
1760 Twine(
" partially ignored") +
1761 Twine(
", possibly due to the lack of a return path."),
1775void PGOUseFunc::annotateIrrLoopHeaderWeights() {
1776 LLVM_DEBUG(
dbgs() <<
"\nAnnotating irreducible loop header weights.\n");
1778 for (
auto &BB :
F) {
1784 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1790void PGOUseFunc::setBlockUniformityAttribute() {
1801 std::vector<BasicBlock *> InstrumentBBs;
1802 FuncInfo.getInstrumentBBs(InstrumentBBs);
1804 LLVMContext &Ctx =
F.getContext();
1805 Type *Int1Ty = Type::getInt1Ty(Ctx);
1807 for (
size_t I = 0,
E = InstrumentBBs.size();
I <
E; ++
I) {
1819 dbgs() <<
"PGO: Set block uniformity profile for " <<
F.getName() <<
": ";
1820 for (
size_t I = 0,
E = InstrumentBBs.size();
I <
E; ++
I)
1826void SelectInstVisitor::instrumentOneSelectInst(SelectInst &SI) {
1829 Type *Int64Ty = Builder.getInt64Ty();
1830 auto *Step = Builder.CreateZExt(
SI.getCondition(), Int64Ty);
1831 auto *NormalizedFuncNameVarPtr =
1833 FuncNameVar, PointerType::get(
M->getContext(), 0));
1834 Builder.CreateIntrinsic(Intrinsic::instrprof_increment_step,
1835 {NormalizedFuncNameVarPtr, Builder.getInt64(
FuncHash),
1836 Builder.getInt32(TotalNumCtrs),
1837 Builder.getInt32(*CurCtrIdx), Step});
1841void SelectInstVisitor::annotateOneSelectInst(SelectInst &SI) {
1842 std::vector<uint64_t> &CountFromProfile = UseFunc->getProfileRecord().Counts;
1843 assert(*CurCtrIdx < CountFromProfile.size() &&
1844 "Out of bound access of counters");
1845 uint64_t SCounts[2];
1846 SCounts[0] = CountFromProfile[*CurCtrIdx];
1848 uint64_t TotalCount = 0;
1849 auto BI = UseFunc->findBBInfo(
SI.getParent());
1850 if (BI !=
nullptr) {
1851 TotalCount = *BI->Count;
1854 if (TotalCount < SCounts[0])
1855 BI->Count = SCounts[0];
1858 SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);
1859 uint64_t MaxCount = std::max(SCounts[0], SCounts[1]);
1864void SelectInstVisitor::visitSelectInst(SelectInst &SI) {
1868 if (
SI.getCondition()->getType()->isVectorTy())
1876 instrumentOneSelectInst(SI);
1879 annotateOneSelectInst(SI);
1887 if (ValueProfKind == IPVK_MemOPSize)
1889 if (ValueProfKind == llvm::IPVK_VTableTarget)
1895void PGOUseFunc::annotateValueSites() {
1902 for (uint32_t Kind = IPVK_First;
Kind <= IPVK_Last; ++
Kind)
1903 annotateValueSites(Kind);
1907void PGOUseFunc::annotateValueSites(uint32_t Kind) {
1908 assert(Kind <= IPVK_Last);
1909 unsigned ValueSiteIndex = 0;
1923 NumValueSites != FuncInfo.ValueSites[IPVK_VTableTarget].size() &&
1925 FuncInfo.ValueSites[IPVK_VTableTarget] = VPC.
get(IPVK_VTableTarget);
1926 auto &ValueSites = FuncInfo.ValueSites[
Kind];
1928 auto &Ctx =
M->getContext();
1929 Ctx.
diagnose(DiagnosticInfoPGOProfile(
1930 M->getName().data(),
1931 Twine(
"Inconsistent number of value sites for ") +
1934 Twine(
"\", possibly due to the use of a stale profile."),
1940 LLVM_DEBUG(
dbgs() <<
"Read one value site profile (kind = " << Kind
1941 <<
"): Index = " << ValueSiteIndex <<
" out of "
1944 *M, *
I.AnnotatedInst, ProfileRecord,
1955 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
1960 ComdatMembers.insert(std::make_pair(
C, &
F));
1962 if (
Comdat *
C = GV.getComdat())
1963 ComdatMembers.insert(std::make_pair(
C, &GV));
1965 if (
Comdat *
C = GA.getComdat())
1966 ComdatMembers.insert(std::make_pair(
C, &GA));
1971 if (
F.isDeclaration())
1976 unsigned NumCriticalEdges = 0;
1977 for (
auto &BB :
F) {
1986 <<
", NumCriticalEdges=" << NumCriticalEdges
1987 <<
" exceed the threshold. Skip PGO.\n");
1997 if (
F.hasFnAttribute(llvm::Attribute::Naked))
1999 if (
F.hasFnAttribute(llvm::Attribute::NoProfile))
2001 if (
F.hasFnAttribute(llvm::Attribute::SkipProfile))
2006 if (
auto EntryCount =
F.getEntryCount())
2024 Triple TT(M.getTargetTriple());
2029 Twine(
"VTable value profiling is presently not "
2030 "supported for non-ELF object formats"),
2032 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
2042 FunctionInstrumenter FI(M,
F, TLI, ComdatMembers, BPI, BFI, LI,
2043 InstrumentationType);
2056 if (ProfileSampling)
2081 InstrumentationType))
2094 auto BFIEntryCount =
F.getEntryCount();
2095 assert(BFIEntryCount && (*BFIEntryCount > 0) &&
"Invalid BFI Entrycount");
2099 for (
auto &BBI :
F) {
2102 if (!Func.findBBInfo(&BBI))
2105 CountValue = *Func.getBBInfo(&BBI).Count;
2106 BFICountValue = *BFICount;
2110 if (SumCount.isZero())
2114 "Incorrect sum of BFI counts");
2117 double Scale = (SumCount / SumBFICount).convertToDouble();
2118 if (Scale < 1.001 && Scale > 0.999)
2123 if (NewEntryCount == 0)
2126 F.setEntryCount(NewEntryCount);
2129 << NewEntryCount <<
"\n");
2146 unsigned BBNum = 0, BBMisMatchNum = 0, NonZeroBBNum = 0;
2147 for (
auto &BBI :
F) {
2148 PGOUseBBInfo *BBInfo = Func.findBBInfo(&BBI);
2152 uint64_t CountValue = BBInfo->Count.value_or(CountValue);
2160 BFICountValue = *BFICount;
2163 bool rawIsHot = CountValue >= HotCountThreshold;
2164 bool BFIIsHot = BFICountValue >= HotCountThreshold;
2166 bool ShowCount =
false;
2167 if (rawIsHot && !BFIIsHot) {
2168 Msg =
"raw-Hot to BFI-nonHot";
2170 }
else if (rawIsCold && BFIIsHot) {
2171 Msg =
"raw-Cold to BFI-Hot";
2180 uint64_t Diff = (BFICountValue >= CountValue)
2181 ? BFICountValue - CountValue
2182 : CountValue - BFICountValue;
2190 F.getSubprogram(), &BBI);
2192 <<
" Count=" <<
ore::NV(
"Count", CountValue)
2193 <<
" BFI_Count=" <<
ore::NV(
"Count", BFICountValue);
2202 F.getSubprogram(), &
F.getEntryBlock())
2203 <<
"In Func " <<
ore::NV(
"Function",
F.getName())
2204 <<
": Num_of_BB=" <<
ore::NV(
"Count", BBNum)
2205 <<
", Num_of_non_zerovalue_BB=" <<
ore::NV(
"Count", NonZeroBBNum)
2206 <<
", Num_of_mis_matching_BB=" <<
ore::NV(
"Count", BBMisMatchNum);
2219 auto &Ctx = M.getContext();
2222 ProfileRemappingFileName);
2223 if (
Error E = ReaderOrErr.takeError()) {
2231 std::unique_ptr<IndexedInstrProfReader> PGOReader =
2232 std::move(ReaderOrErr.get());
2238 if (!PGOReader->hasCSIRLevelProfile() && IsCS)
2242 if (!PGOReader->isIRLevelProfile()) {
2244 ProfileFileName.
data(),
"Not an IR level instrumentation profile"));
2247 if (PGOReader->functionEntryOnly()) {
2249 ProfileFileName.
data(),
2250 "Function entry profiles are not yet supported for optimization"));
2256 if (!
G.hasName() || !
G.hasMetadata(LLVMContext::MD_type))
2267 M.setProfileSummary(PGOReader->getSummary(IsCS).getMD(M.getContext()),
2272 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
2274 std::vector<Function *> HotFunctions;
2275 std::vector<Function *> ColdFunctions;
2279 bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled();
2282 bool InstrumentLoopEntries = PGOReader->instrLoopEntriesEnabled();
2286 bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage();
2294 if (!HasSingleByteCoverage) {
2300 PGOUseFunc Func(
F, &M, TLI, ComdatMembers, BPI, BFI, LI, PSI, IsCS,
2301 InstrumentFuncEntry, InstrumentLoopEntries,
2302 HasSingleByteCoverage);
2303 if (!Func.getRecord(PGOReader.get()))
2305 if (HasSingleByteCoverage) {
2306 Func.populateCoverage();
2314 bool AllZeros =
false;
2315 if (!Func.readCounters(AllZeros, PseudoKind))
2319 if (Func.getProgramMaxCount() != 0)
2320 ColdFunctions.push_back(&
F);
2325 if (
F.hasFnAttribute(Attribute::Cold))
2326 F.removeFnAttr(Attribute::Cold);
2329 F.addFnAttr(Attribute::Hot);
2332 Func.populateCounters();
2333 Func.setBranchWeights();
2334 Func.annotateValueSites();
2335 Func.annotateIrrLoopHeaderWeights();
2336 Func.setBlockUniformityAttribute();
2337 PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();
2338 if (FreqAttr == PGOUseFunc::FFA_Cold)
2339 ColdFunctions.push_back(&
F);
2340 else if (FreqAttr == PGOUseFunc::FFA_Hot)
2341 HotFunctions.push_back(&
F);
2348 std::unique_ptr<BranchProbabilityInfo> NewBPI =
2349 std::make_unique<BranchProbabilityInfo>(
F, CI);
2350 std::unique_ptr<BlockFrequencyInfo> NewBFI =
2351 std::make_unique<BlockFrequencyInfo>(
F, *NewBPI, LI);
2355 dbgs() <<
"pgo-view-counts: " << Func.getFunc().getName() <<
"\n";
2356 NewBFI->print(
dbgs());
2366 ViewGraph(&Func,
Twine(
"PGORawCounts_") + Func.getFunc().getName());
2368 dbgs() <<
"pgo-view-raw-counts: " << Func.getFunc().getName() <<
"\n";
2397 for (
auto &
F : HotFunctions) {
2398 F->addFnAttr(Attribute::InlineHint);
2399 LLVM_DEBUG(
dbgs() <<
"Set inline attribute to function: " <<
F->getName()
2402 for (
auto &
F : ColdFunctions) {
2405 if (
F->hasFnAttribute(Attribute::Hot)) {
2406 auto &Ctx = M.getContext();
2407 std::string
Msg = std::string(
"Function ") +
F->getName().str() +
2408 std::string(
" is annotated as a hot function but"
2409 " the profile is cold");
2414 F->addFnAttr(Attribute::Cold);
2415 LLVM_DEBUG(
dbgs() <<
"Set cold attribute to function: " <<
F->getName()
2422 std::string
Filename, std::string RemappingFilename,
bool IsCS,
2425 ProfileRemappingFileName(
std::
move(RemappingFilename)), IsCS(IsCS),
2454 LookupTLI, LookupBPI, LookupBFI, LookupLI, PSI,
2462 if (!
Node->getName().empty())
2463 return Node->getName().str();
2465 std::string SimpleNodeName;
2468 return SimpleNodeName;
2475 LLVM_DEBUG(
dbgs() <<
"Weight is: ";
for (
const auto &W : Weights) {
2485 if (BrCondStr.empty())
2489 std::accumulate(Weights.begin(), Weights.end(), (
uint64_t)0,
2497 std::string BranchProbStr;
2500 OS <<
" (total count : " << TotalCount <<
")";
2505 << BrCondStr <<
" is true with probability : " << BranchProbStr;
2524 return &
G->getFunc().front();
2547 return std::string(
G->getFunc().getName());
2555 PGOUseBBInfo *BI = Graph->findBBInfo(
Node);
2557 if (BI && BI->Count)
2558 OS << *BI->Count <<
"\\l";
2569 OS <<
"SELECT : { T = ";
2573 OS <<
"Unknown, F = Unknown }\\l";
2575 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...
This file declares the LLVM IR specialization of the GenericCycle templates.
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.
void compute(FunctionT &F)
Compute the cycle info for a function.
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)
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 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."))
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.
RelativeUniformCounterPtr ValuesPtrExpr NumValueSites[IPVK_Last+1]
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,...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
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."))
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."))
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
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.
LLVM_ABI bool isGPUProfTarget(const Module &M)
Determines whether module targets a GPU eligable for PGO instrumentation.
cl::opt< bool > EnableVTableValueProfiling("enable-vtable-value-profiling", cl::init(false), cl::desc("If true, the virtual table address will be instrumented to know " "the types of a C++ pointer. The information is used in indirect " "call promotion to do selective vtable-based comparison."))
static cl::opt< bool > PGOInstrumentEntry("pgo-instrument-entry", cl::init(false), cl::Hidden, cl::desc("Force to instrument function entry basicblock."))
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
static cl::opt< std::string > PGOTraceFuncHash("pgo-trace-func-hash", cl::init("-"), cl::Hidden, cl::value_desc("function name"), cl::desc("Trace the hash of the function with this name."))
cl::opt< bool > NoPGOWarnMismatchComdatWeak
Implement std::hash so that hash_code can be used in STL containers.
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
bool isBlockUniform(unsigned BlockIdx) const
Check if a basic block is entered via a wave-uniform branch.
std::vector< uint64_t > Counts
CountPseudoKind getCountPseudoKind() const
uint32_t getNumValueSites(uint32_t ValueKind) const
Return the number of instrumented sites for ValueKind.
std::vector< uint8_t > UniformityBits
For AMDGPU offload profiling: 1 bit per basic block indicating whether the block is usually entered w...
static void setCSFlagInHash(uint64_t &FuncHash)
static constexpr uint64_t FUNC_HASH_MASK
Instruction * AnnotatedInst