128#include <unordered_map>
135#define DEBUG_TYPE "pgo-instrumentation"
137STATISTIC(NumOfPGOInstrument,
"Number of edges instrumented.");
138STATISTIC(NumOfPGOSelectInsts,
"Number of select instruction instrumented.");
139STATISTIC(NumOfPGOMemIntrinsics,
"Number of mem intrinsics instrumented.");
142STATISTIC(NumOfPGOSplit,
"Number of critical edge splits.");
143STATISTIC(NumOfPGOFunc,
"Number of functions having valid profile counts.");
144STATISTIC(NumOfPGOMismatch,
"Number of functions having mismatch profile.");
145STATISTIC(NumOfPGOMissing,
"Number of functions without profile.");
146STATISTIC(NumOfPGOICall,
"Number of indirect call value instrumentations.");
147STATISTIC(NumOfCSPGOInstrument,
"Number of edges instrumented in CSPGO.");
149 "Number of select instruction instrumented in CSPGO.");
151 "Number of mem intrinsics instrumented in CSPGO.");
153STATISTIC(NumOfCSPGOBB,
"Number of basic-blocks in CSPGO.");
154STATISTIC(NumOfCSPGOSplit,
"Number of critical edge splits in CSPGO.");
156 "Number of functions having valid profile counts in CSPGO.");
158 "Number of functions having mismatch profile in CSPGO.");
159STATISTIC(NumOfCSPGOMissing,
"Number of functions without profile in CSPGO.");
160STATISTIC(NumCoveredBlocks,
"Number of basic blocks that were executed");
168 cl::desc(
"Use this option to turn off/on "
169 "warnings about profile cfg mismatch."));
189 return LibraryOptions.
get<InstrumentationOptions>()
190 .pgo_instrument_cold_function_only;
194class FunctionInstrumenter final {
195 const InstrumentationOptions &Opts;
199 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
210 bool isValueProfilingDisabled()
const {
217 return Opts.disable_vp ||
222 bool shouldInstrumentEntryBB()
const {
223 return valueOr(Opts.pgo_instrument_entry,
false) ||
224 InstrumentationType == PGOInstrumentationType::CTXPROF;
227 bool shouldInstrumentLoopEntries()
const {
228 return valueOr(Opts.pgo_instrument_loop_entries,
false);
232 FunctionInstrumenter(
234 TargetLibraryInfo &TLI,
235 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
236 BranchProbabilityInfo *BPI =
nullptr, BlockFrequencyInfo *BFI =
nullptr,
237 LoopInfo *LI =
nullptr,
239 : Opts(Opts), M(M), F(F), TLI(TLI), ComdatMembers(ComdatMembers),
240 BPI(BPI), BFI(BFI), LI(LI), InstrumentationType(InstrumentationType) {}
251 return std::string();
256 return std::string();
268 else if (CV->
isOne())
279#define VALUE_PROF_KIND(Enumerator, Value, Descr) Descr,
293 if (
valueOr(Opts.pgo_instrument_entry,
false) ||
296 if (
valueOr(Opts.pgo_instrument_loop_entries,
false))
300 if (Opts.pgo_function_entry_coverage)
303 if (Opts.pgo_block_coverage)
305 if (Opts.pgo_temporal_instrumentation)
312 Triple TT(M.getTargetTriple());
313 if (TT.supportsCOMDAT()) {
315 IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName));
317 return IRLevelVersionVariable;
327enum VisitMode { VM_counting, VM_instrument, VM_annotate };
331struct SelectInstVisitor :
public InstVisitor<SelectInstVisitor> {
332 const InstrumentationOptions &Opts;
335 VisitMode Mode = VM_counting;
336 unsigned *CurCtrIdx =
nullptr;
337 unsigned TotalNumCtrs = 0;
338 GlobalValue *FuncNameVar =
nullptr;
340 PGOUseFunc *UseFunc =
nullptr;
341 bool HasSingleByteCoverage;
343 SelectInstVisitor(
const InstrumentationOptions &Opts,
Function &Func,
344 bool HasSingleByteCoverage)
345 : Opts(Opts), F(
Func), HasSingleByteCoverage(HasSingleByteCoverage) {}
347 void countSelects() {
357 void instrumentSelects(
unsigned *Ind,
unsigned TotalNC, GlobalValue *FNV,
359 Mode = VM_instrument;
361 TotalNumCtrs = TotalNC;
368 void annotateSelects(PGOUseFunc *UF,
unsigned *Ind) {
375 void instrumentOneSelectInst(SelectInst &SI);
376 void annotateOneSelectInst(SelectInst &SI);
379 void visitSelectInst(SelectInst &SI);
383 unsigned getNumOfSelectInsts()
const {
return NSIs; }
395 bool Removed =
false;
396 bool IsCritical =
false;
398 PGOEdge(BasicBlock *Src, BasicBlock *Dest,
uint64_t W = 1)
399 : SrcBB(Src), DestBB(Dest), Weight(
W) {}
402 std::string infoString()
const {
403 return (Twine(Removed ?
"-" :
" ") + (InMST ?
" " :
"*") +
404 (IsCritical ?
"c" :
" ") +
" W=" + Twine(Weight))
415 PGOBBInfo(
unsigned IX) : Group(this), Index(IX) {}
418 std::string infoString()
const {
419 return (Twine(
"Index=") + Twine(Index)).str();
424template <
class Edge,
class BBInfo>
class FuncPGOInstrumentation {
426 const InstrumentationOptions &Opts;
433 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
435 ValueProfileCollector VPC;
437 void computeCFGHash();
438 void renameComdatFunction();
441 const TargetLibraryInfo &TLI;
442 std::vector<std::vector<VPCandidateInfo>> ValueSites;
443 SelectInstVisitor SIVisitor;
444 std::string FuncName;
445 std::string DeprecatedFuncName;
446 GlobalVariable *FuncNameVar;
452 CFGMST<Edge, BBInfo> MST;
454 const std::optional<BlockCoverageInference> BCI;
456 static std::optional<BlockCoverageInference>
457 constructBCI(
Function &Func,
bool HasSingleByteCoverage,
458 bool InstrumentFuncEntry) {
459 if (HasSingleByteCoverage)
460 return BlockCoverageInference(Func, InstrumentFuncEntry);
466 void getInstrumentBBs(std::vector<BasicBlock *> &InstrumentBBs);
473 BBInfo &getBBInfo(
const BasicBlock *BB)
const {
return MST.getBBInfo(BB); }
476 BBInfo *findBBInfo(
const BasicBlock *BB)
const {
return MST.findBBInfo(BB); }
479 void dumpInfo(StringRef Str =
"")
const {
480 MST.dumpEdges(
dbgs(), Twine(
"Dump Function ") + FuncName +
481 " Hash: " + Twine(FunctionHash) +
"\t" + Str);
484 FuncPGOInstrumentation(
485 const InstrumentationOptions &Opts,
Function &Func,
486 TargetLibraryInfo &TLI,
487 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
488 bool CreateGlobalVar =
false, BranchProbabilityInfo *BPI =
nullptr,
489 BlockFrequencyInfo *BFI =
nullptr, LoopInfo *LI =
nullptr,
490 bool IsCS =
false,
bool InstrumentFuncEntry =
true,
491 bool InstrumentLoopEntries =
false,
bool HasSingleByteCoverage =
false)
492 : Opts(Opts), F(
Func), IsCS(IsCS), ComdatMembers(ComdatMembers),
493 VPC(
Func, TLI), TLI(TLI), ValueSites(IPVK_Last + 1),
494 SIVisitor(Opts,
Func, HasSingleByteCoverage),
495 MST(F, InstrumentFuncEntry, InstrumentLoopEntries, BPI, BFI, LI),
496 BCI(constructBCI(
Func, HasSingleByteCoverage, InstrumentFuncEntry)) {
497 if (BCI && Opts.pgo_view_block_coverage_graph)
498 BCI->viewBlockCoverageGraph();
500 SIVisitor.countSelects();
501 ValueSites[IPVK_MemOPSize] = VPC.get(IPVK_MemOPSize);
503 NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
504 NumOfPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
505 NumOfPGOBB += MST.bbInfoSize();
506 ValueSites[IPVK_IndirectCallTarget] = VPC.get(IPVK_IndirectCallTarget);
508 ValueSites[IPVK_VTableTarget] = VPC.get(IPVK_VTableTarget);
510 NumOfCSPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
511 NumOfCSPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
512 NumOfCSPGOBB += MST.bbInfoSize();
518 if (!ComdatMembers.empty())
519 renameComdatFunction();
522 for (
const auto &
E : MST.allEdges()) {
525 IsCS ? NumOfCSPGOEdge++ : NumOfPGOEdge++;
527 IsCS ? NumOfCSPGOInstrument++ : NumOfPGOInstrument++;
540template <
class Edge,
class BBInfo>
541void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
542 std::vector<uint8_t> Indexes;
546 auto BI = findBBInfo(Succ);
550 for (
int J = 0; J < 4; J++)
551 Indexes.push_back((
uint8_t)(Index >> (J * 8)));
558 auto updateJCH = [&JCH](
uint64_t Num) {
563 updateJCH((
uint64_t)SIVisitor.getNumOfSelectInsts());
564 updateJCH((
uint64_t)ValueSites[IPVK_IndirectCallTarget].
size());
567 updateJCH(BCI->getInstrumentedBlocksHash());
580 LLVM_DEBUG(
dbgs() <<
"Function Hash Computation for " <<
F.getName() <<
":\n"
581 <<
" CRC = " << JC.
getCRC()
582 <<
", Selects = " << SIVisitor.getNumOfSelectInsts()
583 <<
", Edges = " << MST.
numEdges() <<
", ICSites = "
584 << ValueSites[IPVK_IndirectCallTarget].size()
585 <<
", Memops = " << ValueSites[IPVK_MemOPSize].size()
586 <<
", High32 CRC = " << JCH.
getCRC()
587 <<
", Hash = " << FunctionHash <<
"\n";);
589 if (Opts.pgo_trace_func_hash !=
"-" &&
590 F.getName().contains(Opts.pgo_trace_func_hash))
591 dbgs() <<
"Funcname=" <<
F.getName() <<
", Hash=" << FunctionHash
592 <<
" in building " <<
F.getParent()->getSourceFileName() <<
"\n";
597 const InstrumentationOptions &Opts,
Function &
F,
598 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
610 for (
auto &&CM :
make_range(ComdatMembers.equal_range(
C))) {
620template <
class Edge,
class BBInfo>
621void FuncPGOInstrumentation<Edge, BBInfo>::renameComdatFunction() {
624 std::string OrigName =
F.getName().str();
625 std::string NewFuncName =
627 F.setName(
Twine(NewFuncName));
629 FuncName =
Twine(FuncName +
"." +
Twine(FunctionHash)).
str();
635 if (!
F.hasComdat()) {
637 NewComdat = M->getOrInsertComdat(
StringRef(NewFuncName));
639 F.setComdat(NewComdat);
644 Comdat *OrigComdat =
F.getComdat();
645 std::string NewComdatName =
647 NewComdat = M->getOrInsertComdat(
StringRef(NewComdatName));
650 for (
auto &&CM :
make_range(ComdatMembers.equal_range(OrigComdat))) {
658template <
class Edge,
class BBInfo>
659void FuncPGOInstrumentation<Edge, BBInfo>::getInstrumentBBs(
660 std::vector<BasicBlock *> &InstrumentBBs) {
663 if (BCI->shouldInstrumentBlock(BB))
664 InstrumentBBs.push_back(&BB);
669 std::vector<Edge *> EdgeList;
672 EdgeList.push_back(
E.get());
674 for (
auto &
E : EdgeList) {
677 InstrumentBBs.push_back(InstrBB);
683template <
class Edge,
class BBInfo>
684BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *
E) {
685 if (
E->InMST ||
E->Removed)
691 if (SrcBB ==
nullptr)
693 if (DestBB ==
nullptr)
708 return canInstrument(SrcBB);
710 return canInstrument(DestBB);
719 dbgs() <<
"Fail to split critical edge: not instrument this edge.\n");
724 IsCS ? NumOfCSPGOSplit++ : NumOfPGOSplit++;
725 LLVM_DEBUG(
dbgs() <<
"Split critical edge: " << getBBInfo(SrcBB).Index
726 <<
" --> " << getBBInfo(DestBB).Index <<
"\n");
728 MST.
addEdge(SrcBB, InstrBB, 0);
730 Edge &NewEdge1 = MST.
addEdge(InstrBB, DestBB, 0);
731 NewEdge1.InMST =
true;
734 return canInstrument(InstrBB);
753 std::optional<OperandBundleUse> ParentFunclet =
761 if (!BlockColors.
empty()) {
762 const ColorVector &CV = BlockColors.
find(OrigCall->getParent())->second;
763 assert(CV.
size() == 1 &&
"non-unique color for block!");
765 if (EHPadIt->isEHPad())
773void FunctionInstrumenter::instrument() {
774 if (!Opts.pgo_block_coverage) {
780 const bool IsCtxProf = InstrumentationType == PGOInstrumentationType::CTXPROF;
781 FuncPGOInstrumentation<PGOEdge, PGOBBInfo> FuncInfo(
782 Opts,
F, TLI, ComdatMembers, !IsCtxProf, BPI, BFI, LI,
783 InstrumentationType == PGOInstrumentationType::CSFDO,
784 shouldInstrumentEntryBB(), shouldInstrumentLoopEntries(),
785 Opts.pgo_block_coverage);
788 auto *
const CFGHash =
789 ConstantInt::get(Type::getInt64Ty(
M.getContext()), FuncInfo.FunctionHash);
793 Name, PointerType::get(
M.getContext(), 0));
794 if (Opts.pgo_function_entry_coverage) {
795 auto &EntryBB =
F.getEntryBlock();
796 IRBuilder<> Builder(EntryBB.getFirstNonPHIOrAlloca());
799 Builder.CreateIntrinsic(
800 Intrinsic::instrprof_cover,
801 {NormalizedNamePtr, CFGHash, Builder.getInt32(1), Builder.getInt32(0)});
805 std::vector<BasicBlock *> InstrumentBBs;
806 FuncInfo.getInstrumentBBs(InstrumentBBs);
807 unsigned NumCounters =
808 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
812 Opts.ctx_prof_skip_callsite_instr);
824 auto Visit = [&](llvm::function_ref<void(CallBase * CB)> Visitor) {
826 for (
auto &Instr : BB)
830 if (CS->getCalledFunction() &&
831 SkipCSInstr.contains(CS->getCalledFunction()->getName()))
837 uint32_t TotalNumCallsites = 0;
838 Visit([&TotalNumCallsites](
auto *) { ++TotalNumCallsites; });
842 Visit([&](
auto *CB) {
844 Builder.CreateCall(CSIntrinsic,
845 {
Name, CFGHash, Builder.getInt32(TotalNumCallsites),
847 CB->getCalledOperand()});
852 if (Opts.pgo_temporal_instrumentation) {
853 NumCounters += Opts.pgo_block_coverage ? 8 : 1;
854 auto &EntryBB =
F.getEntryBlock();
855 IRBuilder<> Builder(EntryBB.getFirstNonPHIOrAlloca());
858 Builder.CreateIntrinsic(Intrinsic::instrprof_timestamp,
859 {NormalizedNamePtr, CFGHash,
860 Builder.getInt32(NumCounters),
861 Builder.getInt32(
I)});
862 I += Opts.pgo_block_coverage ? 8 : 1;
865 for (
auto *InstrBB : InstrumentBBs) {
867 assert(Builder.GetInsertPoint() != InstrBB->
end() &&
868 "Cannot get the Instrumentation point");
871 Builder.CreateIntrinsic(
872 Opts.pgo_block_coverage ? Intrinsic::instrprof_cover
873 : Intrinsic::instrprof_increment,
874 {NormalizedNamePtr, CFGHash, Builder.getInt32(NumCounters),
875 Builder.getInt32(I++)});
879 FuncInfo.SIVisitor.instrumentSelects(&
I, NumCounters, Name,
880 FuncInfo.FunctionHash);
883 if (isValueProfilingDisabled())
886 NumOfPGOICall += FuncInfo.ValueSites[IPVK_IndirectCallTarget].size();
892 DenseMap<BasicBlock *, ColorVector> BlockColors;
893 if (
F.hasPersonalityFn() &&
898 for (uint32_t Kind = IPVK_First;
Kind <= IPVK_Last; ++
Kind) {
899 unsigned SiteIndex = 0;
900 if (Kind == IPVK_MemOPSize && !Opts.pgo_instr_memop)
905 <<
" site: CallSite Index = " << SiteIndex <<
"\n");
908 assert(Builder.GetInsertPoint() != Cand.InsertPt->getParent()->end() &&
909 "Cannot get the Instrumentation point");
911 Value *ToProfile =
nullptr;
912 if (Cand.V->getType()->isIntegerTy())
913 ToProfile = Builder.CreateZExtOrTrunc(Cand.V, Builder.getInt64Ty());
914 else if (Cand.V->getType()->isPointerTy())
915 ToProfile = Builder.CreatePtrToInt(Cand.V, Builder.getInt64Ty());
916 assert(ToProfile &&
"value profiling Value is of unexpected type");
919 Name, PointerType::get(
M.getContext(), 0));
925 Intrinsic::instrprof_value_profile),
926 {NormalizedNamePtr, Builder.getInt64(FuncInfo.FunctionHash),
927 ToProfile, Builder.getInt32(Kind), Builder.getInt32(SiteIndex++)},
936struct PGOUseEdge :
public PGOEdge {
937 using PGOEdge::PGOEdge;
939 std::optional<uint64_t>
Count;
945 std::string infoString()
const {
947 return PGOEdge::infoString();
948 return (Twine(PGOEdge::infoString()) +
" Count=" + Twine(*
Count)).str();
955struct PGOUseBBInfo :
public PGOBBInfo {
956 std::optional<uint64_t>
Count;
957 int32_t UnknownCountInEdge = 0;
958 int32_t UnknownCountOutEdge = 0;
960 DirectEdges OutEdges;
962 PGOUseBBInfo(
unsigned IX) : PGOBBInfo(IX) {}
968 std::string infoString()
const {
970 return PGOBBInfo::infoString();
971 return (Twine(PGOBBInfo::infoString()) +
" Count=" + Twine(*
Count)).str();
975 void addOutEdge(PGOUseEdge *
E) {
976 OutEdges.push_back(
E);
977 UnknownCountOutEdge++;
981 void addInEdge(PGOUseEdge *
E) {
982 InEdges.push_back(
E);
983 UnknownCountInEdge++;
992 for (
const auto &
E : Edges) {
1005 PGOUseFunc(
const InstrumentationOptions &Opts,
Function &Func,
Module *Modu,
1006 TargetLibraryInfo &TLI,
1007 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
1008 BranchProbabilityInfo *BPI, BlockFrequencyInfo *BFIin,
1009 LoopInfo *LI, ProfileSummaryInfo *PSI,
bool IsCS,
1010 bool InstrumentFuncEntry,
bool InstrumentLoopEntries,
1011 bool HasSingleByteCoverage)
1012 : Opts(Opts),
F(
Func),
M(Modu), BFI(BFIin), PSI(PSI),
1013 FuncInfo(Opts,
Func, TLI, ComdatMembers,
false, BPI, BFIin, LI, IsCS,
1014 InstrumentFuncEntry, InstrumentLoopEntries,
1015 HasSingleByteCoverage),
1016 FreqAttr(FFA_Normal), IsCS(IsCS), VPC(
Func, TLI) {}
1018 void handleInstrProfError(
Error Err,
uint64_t MismatchedFuncSum);
1023 bool getRecord(IndexedInstrProfReader *PGOReader);
1026 bool readCounters(
bool &AllZeros,
1030 void populateCounters();
1033 void populateCoverage();
1039 void annotateValueSites();
1042 void annotateValueSites(uint32_t Kind);
1045 void annotateIrrLoopHeaderWeights();
1048 void setBlockUniformityAttribute();
1051 enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };
1054 FuncFreqAttr getFuncFreqAttr()
const {
return FreqAttr; }
1060 NamedInstrProfRecord &getProfileRecord() {
return ProfileRecord; }
1063 PGOUseBBInfo &getBBInfo(
const BasicBlock *BB)
const {
1064 return FuncInfo.getBBInfo(BB);
1068 PGOUseBBInfo *findBBInfo(
const BasicBlock *BB)
const {
1069 return FuncInfo.findBBInfo(BB);
1074 void dumpInfo(StringRef Str =
"")
const { FuncInfo.dumpInfo(Str); }
1076 uint64_t getProgramMaxCount()
const {
return ProgramMaxCount; }
1079 const InstrumentationOptions &Opts;
1082 BlockFrequencyInfo *BFI;
1083 ProfileSummaryInfo *PSI;
1086 FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> FuncInfo;
1093 uint32_t CountPosition = 0;
1096 uint32_t ProfileCountSize = 0;
1099 NamedInstrProfRecord ProfileRecord;
1102 FuncFreqAttr FreqAttr;
1107 ValueProfileCollector VPC;
1110 bool setInstrumentedCounts(
const std::vector<uint64_t> &CountFromProfile);
1123 FreqAttr = FFA_Cold;
1131 const FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> &FuncInfo) {
1135 for (
const auto &
E : FuncInfo.MST.allEdges()) {
1140 PGOUseBBInfo &SrcInfo = FuncInfo.getBBInfo(SrcBB);
1141 PGOUseBBInfo &DestInfo = FuncInfo.getBBInfo(DestBB);
1142 SrcInfo.addOutEdge(
E.get());
1143 DestInfo.addInEdge(
E.get());
1149bool PGOUseFunc::setInstrumentedCounts(
1150 const std::vector<uint64_t> &CountFromProfile) {
1152 std::vector<BasicBlock *> InstrumentBBs;
1153 FuncInfo.getInstrumentBBs(InstrumentBBs);
1157 unsigned NumInstrumentedBBs = InstrumentBBs.size();
1158 unsigned NumSelects = FuncInfo.SIVisitor.getNumOfSelectInsts();
1159 unsigned NumCounters = NumInstrumentedBBs + NumSelects;
1162 if (NumCounters != CountFromProfile.size()) {
1164 dbgs() <<
"PGO COUNTER MISMATCH for function " <<
F.getName() <<
":\n";
1165 dbgs() <<
" Expected counters: " << NumCounters <<
"\n";
1166 dbgs() <<
" - From instrumented edges: " << NumInstrumentedBBs <<
"\n";
1167 for (
size_t i = 0; i < InstrumentBBs.size(); ++i) {
1168 dbgs() <<
" " << i <<
": ";
1169 InstrumentBBs[i]->printAsOperand(
dbgs(),
false);
1172 dbgs() <<
" - From select instructions: " << NumSelects <<
"\n";
1173 dbgs() <<
" Actual counters from profile: " << CountFromProfile.size()
1178 auto *FuncEntry = &*
F.begin();
1182 for (BasicBlock *InstrBB : InstrumentBBs) {
1183 uint64_t CountValue = CountFromProfile[
I++];
1184 PGOUseBBInfo &
Info = getBBInfo(InstrBB);
1188 if (InstrBB == FuncEntry && CountValue == 0)
1190 Info.setBBInfoCount(CountValue);
1192 ProfileCountSize = CountFromProfile.size();
1196 auto setEdgeCount = [
this](PGOUseEdge *
E,
uint64_t Value) ->
void {
1198 this->getBBInfo(
E->SrcBB).UnknownCountOutEdge--;
1199 this->getBBInfo(
E->DestBB).UnknownCountInEdge--;
1205 for (
const auto &
E : FuncInfo.MST.allEdges()) {
1206 if (
E->Removed ||
E->InMST)
1209 PGOUseBBInfo &SrcInfo = getBBInfo(SrcBB);
1213 if (SrcInfo.Count && SrcInfo.OutEdges.size() == 1)
1214 setEdgeCount(
E.get(), *SrcInfo.Count);
1217 PGOUseBBInfo &DestInfo = getBBInfo(DestBB);
1220 if (DestInfo.Count && DestInfo.InEdges.size() == 1)
1221 setEdgeCount(
E.get(), *DestInfo.Count);
1227 setEdgeCount(
E.get(), 0);
1234void PGOUseFunc::setEdgeCount(DirectEdges &Edges,
uint64_t Value) {
1235 for (
auto &
E : Edges) {
1240 getBBInfo(
E->SrcBB).UnknownCountOutEdge--;
1241 getBBInfo(
E->DestBB).UnknownCountInEdge--;
1249 const char MetadataName[] =
"instr_prof_hash_mismatch";
1252 auto *Existing =
F.getMetadata(LLVMContext::MD_annotation);
1255 for (
const auto &
N : Tuple->operands()) {
1256 if (
N.equalsStr(MetadataName))
1265 F.setMetadata(LLVMContext::MD_annotation, MD);
1268void PGOUseFunc::handleInstrProfError(
Error Err,
uint64_t MismatchedFuncSum) {
1270 auto &Ctx =
M->getContext();
1271 auto Err = IPE.
get();
1272 bool SkipWarning =
false;
1274 << FuncInfo.FuncName <<
": ");
1275 if (Err == instrprof_error::unknown_function) {
1276 IsCS ? NumOfCSPGOMissing++ : NumOfPGOMissing++;
1277 SkipWarning = !Opts.pgo_warn_missing_function;
1279 }
else if (Err == instrprof_error::hash_mismatch ||
1280 Err == instrprof_error::malformed) {
1281 IsCS ? NumOfCSPGOMismatch++ : NumOfPGOMismatch++;
1284 (Opts.no_pgo_warn_mismatch_comdat_weak &&
1287 LLVM_DEBUG(
dbgs() <<
"hash mismatch (hash= " << FuncInfo.FunctionHash
1288 <<
" skip=" << SkipWarning <<
")");
1298 IPE.
message() + std::string(
" ") +
F.getName().str() +
1299 std::string(
" Hash = ") + std::to_string(FuncInfo.FunctionHash) +
1300 std::string(
" up to ") + std::to_string(MismatchedFuncSum) +
1301 std::string(
" count discarded");
1308bool PGOUseFunc::getRecord(IndexedInstrProfReader *PGOReader) {
1311 FuncInfo.FuncName, FuncInfo.FunctionHash, FuncInfo.DeprecatedFuncName,
1312 &MismatchedFuncSum);
1314 handleInstrProfError(std::move(
E), MismatchedFuncSum);
1317 ProfileRecord = std::move(
Result.get());
1325bool PGOUseFunc::readCounters(
bool &AllZeros,
1327 auto &Ctx =
M->getContext();
1332 std::vector<uint64_t> &CountFromProfile = ProfileRecord.
Counts;
1334 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1338 for (
unsigned I = 0, S = CountFromProfile.size();
I < S;
I++) {
1340 ValueSum += CountFromProfile[
I];
1342 AllZeros = (ValueSum == 0);
1346 getBBInfo(
nullptr).UnknownCountOutEdge = 2;
1347 getBBInfo(
nullptr).UnknownCountInEdge = 2;
1349 if (!setInstrumentedCounts(CountFromProfile)) {
1351 dbgs() <<
"Inconsistent number of counts, skipping this function");
1352 Ctx.diagnose(DiagnosticInfoPGOProfile(
1353 M->getName().data(),
1354 Twine(
"Inconsistent number of counts in ") +
F.getName().str() +
1355 Twine(
": the profile may be stale or there is a function name "
1363void PGOUseFunc::populateCoverage() {
1364 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1366 ArrayRef<uint64_t> CountsFromProfile = ProfileRecord.
Counts;
1367 DenseMap<const BasicBlock *, bool>
Coverage;
1370 if (FuncInfo.BCI->shouldInstrumentBlock(BB))
1375 DenseMap<const BasicBlock *, DenseSet<const BasicBlock *>>
1376 InverseDependencies;
1377 for (
auto &BB :
F) {
1378 for (
auto *Dep : FuncInfo.BCI->getDependencies(BB)) {
1380 InverseDependencies[Dep].
insert(&BB);
1385 std::stack<const BasicBlock *> CoveredBlocksToProcess;
1386 for (
auto &[BB, IsCovered] : Coverage)
1388 CoveredBlocksToProcess.push(BB);
1390 while (!CoveredBlocksToProcess.empty()) {
1391 auto *CoveredBlock = CoveredBlocksToProcess.top();
1392 assert(Coverage[CoveredBlock]);
1393 CoveredBlocksToProcess.pop();
1394 for (
auto *BB : InverseDependencies[CoveredBlock]) {
1400 CoveredBlocksToProcess.push(BB);
1405 MDBuilder MDB(
F.getContext());
1408 F.setEntryCount(Coverage[&
F.getEntryBlock()] ? 10000 : 0);
1409 for (
auto &BB :
F) {
1416 SmallVector<uint32_t, 4> Weights;
1418 Weights.
push_back((Coverage[Succ] || !Coverage[&BB]) ? 1 : 0);
1419 if (Weights.
size() >= 2)
1424 unsigned NumCorruptCoverage = 0;
1427 BranchProbabilityInfo BPI(
F, CI);
1428 BlockFrequencyInfo BFI(
F, BPI, CI);
1429 auto IsBlockDead = [&](
const BasicBlock &BB) -> std::optional<bool> {
1434 LLVM_DEBUG(
dbgs() <<
"Block Coverage: (Instrumented=*, Covered=X)\n");
1435 for (
auto &BB :
F) {
1436 LLVM_DEBUG(
dbgs() << (FuncInfo.BCI->shouldInstrumentBlock(BB) ?
"* " :
" ")
1437 << (Coverage[&BB] ?
"X " :
" ") <<
" " << BB.getName()
1444 if (Cov == IsBlockDead(BB).value_or(
false)) {
1446 dbgs() <<
"Found inconsistent block covearge for " << BB.getName()
1447 <<
": BCI=" << (Cov ?
"Covered" :
"Dead") <<
" BFI="
1448 << (IsBlockDead(BB).value() ?
"Dead" :
"Covered") <<
"\n");
1449 ++NumCorruptCoverage;
1454 if (Opts.pgo_verify_bfi && NumCorruptCoverage) {
1455 auto &Ctx =
M->getContext();
1456 Ctx.diagnose(DiagnosticInfoPGOProfile(
1457 M->getName().data(),
1458 Twine(
"Found inconsistent block coverage for function ") +
F.getName() +
1459 " in " + Twine(NumCorruptCoverage) +
" blocks.",
1462 if (Opts.pgo_view_block_coverage_graph)
1463 FuncInfo.BCI->viewBlockCoverageGraph(&Coverage);
1468void PGOUseFunc::populateCounters() {
1469 bool Changes =
true;
1470 unsigned NumPasses = 0;
1478 PGOUseBBInfo *UseBBInfo = findBBInfo(&BB);
1479 if (UseBBInfo ==
nullptr)
1481 if (!UseBBInfo->Count) {
1482 if (UseBBInfo->UnknownCountOutEdge == 0) {
1485 }
else if (UseBBInfo->UnknownCountInEdge == 0) {
1490 if (UseBBInfo->Count) {
1491 if (UseBBInfo->UnknownCountOutEdge == 1) {
1497 if (*UseBBInfo->Count > OutSum)
1498 Total = *UseBBInfo->Count - OutSum;
1499 setEdgeCount(UseBBInfo->OutEdges,
Total);
1502 if (UseBBInfo->UnknownCountInEdge == 1) {
1505 if (*UseBBInfo->Count > InSum)
1506 Total = *UseBBInfo->Count - InSum;
1507 setEdgeCount(UseBBInfo->InEdges,
Total);
1514 LLVM_DEBUG(
dbgs() <<
"Populate counts in " << NumPasses <<
" passes.\n");
1518 for (
auto &BB :
F) {
1519 auto BI = findBBInfo(&BB);
1522 assert(BI->Count &&
"BB count is not valid");
1526 FuncInfo.SIVisitor.annotateSelects(
this, &CountPosition);
1527 assert(CountPosition == ProfileCountSize);
1531 for (
auto &BB :
F) {
1532 auto BI = findBBInfo(&BB);
1535 FuncMaxCount = std::max(FuncMaxCount, *BI->Count);
1544 LLVM_DEBUG(FuncInfo.dumpInfo(
"after reading profile."));
1548void PGOUseFunc::setBranchWeights() {
1550 LLVM_DEBUG(
dbgs() <<
"\nSetting branch weights for func " <<
F.getName()
1551 <<
" IsCS=" << IsCS <<
"\n");
1552 for (
auto &BB :
F) {
1561 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1562 if (!*BBCountInfo.Count)
1569 unsigned OutEdgesCount = BBCountInfo.OutEdges.size();
1570 unsigned SuccessorCount = BB.getTerminator()->getNumSuccessors();
1571 assert(OutEdgesCount <= SuccessorCount);
1575 for (
unsigned It = 0; It < OutEdgesCount; It++) {
1576 const PGOUseEdge *
E = BBCountInfo.OutEdges[It];
1579 if (DestBB ==
nullptr)
1583 if (EdgeCount > MaxCount)
1584 MaxCount = EdgeCount;
1585 EdgeCounts[SuccNum] = EdgeCount;
1594 auto &Ctx =
M->getContext();
1595 Ctx.diagnose(DiagnosticInfoPGOProfile(
1596 M->getName().data(),
1597 Twine(
"Profile in ") +
F.getName().str() +
1598 Twine(
" partially ignored") +
1599 Twine(
", possibly due to the lack of a return path."),
1613void PGOUseFunc::annotateIrrLoopHeaderWeights() {
1614 LLVM_DEBUG(
dbgs() <<
"\nAnnotating irreducible loop header weights.\n");
1616 for (
auto &BB :
F) {
1622 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1628void PGOUseFunc::setBlockUniformityAttribute() {
1639 std::vector<BasicBlock *> InstrumentBBs;
1640 FuncInfo.getInstrumentBBs(InstrumentBBs);
1642 LLVMContext &Ctx =
F.getContext();
1643 Type *Int1Ty = Type::getInt1Ty(Ctx);
1645 for (
size_t I = 0,
E = InstrumentBBs.size();
I <
E; ++
I) {
1657 dbgs() <<
"PGO: Set block uniformity profile for " <<
F.getName() <<
": ";
1658 for (
size_t I = 0,
E = InstrumentBBs.size();
I <
E; ++
I)
1664void SelectInstVisitor::instrumentOneSelectInst(SelectInst &SI) {
1667 Type *Int64Ty = Builder.getInt64Ty();
1673 auto *Step = Builder.CreateZExt(
Cond, Int64Ty);
1674 auto *NormalizedFuncNameVarPtr =
1676 FuncNameVar, PointerType::get(
M->getContext(), 0));
1677 Builder.CreateIntrinsic(Intrinsic::instrprof_increment_step,
1678 {NormalizedFuncNameVarPtr, Builder.getInt64(
FuncHash),
1679 Builder.getInt32(TotalNumCtrs),
1680 Builder.getInt32(*CurCtrIdx), Step});
1684void SelectInstVisitor::annotateOneSelectInst(SelectInst &SI) {
1685 std::vector<uint64_t> &CountFromProfile = UseFunc->getProfileRecord().Counts;
1686 assert(*CurCtrIdx < CountFromProfile.size() &&
1687 "Out of bound access of counters");
1689 SCounts[0] = CountFromProfile[*CurCtrIdx];
1692 auto BI = UseFunc->findBBInfo(
SI.getParent());
1693 if (BI !=
nullptr) {
1694 TotalCount = *BI->Count;
1697 if (TotalCount < SCounts[0])
1698 BI->Count = SCounts[0];
1701 SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);
1702 uint64_t MaxCount = std::max(SCounts[0], SCounts[1]);
1707void SelectInstVisitor::visitSelectInst(SelectInst &SI) {
1708 if (!Opts.pgo_instr_select || Opts.pgo_function_entry_coverage ||
1709 HasSingleByteCoverage)
1712 if (
SI.getCondition()->getType()->isVectorTy())
1720 instrumentOneSelectInst(SI);
1723 annotateOneSelectInst(SI);
1732 if (ValueProfKind == IPVK_MemOPSize)
1733 return Opts.memop_max_annotations;
1734 if (ValueProfKind == llvm::IPVK_VTableTarget)
1736 return Opts.icp_max_annotations;
1740void PGOUseFunc::annotateValueSites() {
1741 if (Opts.disable_vp)
1744 for (uint32_t Kind = IPVK_First;
Kind <= IPVK_Last; ++
Kind)
1745 annotateValueSites(Kind);
1749void PGOUseFunc::annotateValueSites(uint32_t Kind) {
1750 assert(Kind <= IPVK_Last);
1751 unsigned ValueSiteIndex = 0;
1765 NumValueSites != FuncInfo.ValueSites[IPVK_VTableTarget].size() &&
1767 FuncInfo.ValueSites[IPVK_VTableTarget] = VPC.
get(IPVK_VTableTarget);
1768 auto &ValueSites = FuncInfo.ValueSites[
Kind];
1770 auto &Ctx =
M->getContext();
1771 Ctx.
diagnose(DiagnosticInfoPGOProfile(
1772 M->getName().data(),
1773 Twine(
"Inconsistent number of value sites for ") +
1776 Twine(
"\", possibly due to the use of a stale profile."),
1782 LLVM_DEBUG(
dbgs() <<
"Read one value site profile (kind = " << Kind
1783 <<
"): Index = " << ValueSiteIndex <<
" out of "
1786 *M, *
I.AnnotatedInst, ProfileRecord,
1796 const InstrumentationOptions &Opts,
Module &M,
1797 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
1798 if (!Opts.do_comdat_renaming)
1802 ComdatMembers.insert(std::make_pair(
C, &
F));
1804 if (
Comdat *
C = GV.getComdat())
1805 ComdatMembers.insert(std::make_pair(
C, &GV));
1807 if (
Comdat *
C = GA.getComdat())
1808 ComdatMembers.insert(std::make_pair(
C, &GA));
1813 if (
F.isDeclaration())
1818 unsigned NumCriticalEdges = 0;
1819 for (
auto &BB :
F) {
1826 if (NumCriticalEdges > Opts.pgo_critical_edge_threshold) {
1828 <<
", NumCriticalEdges=" << NumCriticalEdges
1829 <<
" exceed the threshold. Skip PGO.\n");
1839 if (
F.hasFnAttribute(llvm::Attribute::Naked))
1841 if (
F.hasFnAttribute(llvm::Attribute::NoProfile))
1843 if (
F.hasFnAttribute(llvm::Attribute::SkipProfile))
1845 if (
F.getInstructionCount() < Opts.pgo_function_size_threshold)
1847 if (Opts.pgo_instrument_cold_function_only) {
1848 if (
auto EntryCount =
F.getEntryCount())
1849 return *EntryCount > Opts.pgo_cold_instrument_entry_threshold;
1850 return !Opts.pgo_treat_unknown_as_cold;
1856 const InstrumentationOptions &Opts,
Module &M,
1867 Triple TT(M.getTargetTriple());
1872 Twine(
"VTable value profiling is presently not "
1873 "supported for non-ELF object formats"),
1875 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
1885 FunctionInstrumenter FI(Opts, M,
F, TLI, ComdatMembers, BPI, BFI, LI,
1886 InstrumentationType);
1895 const InstrumentationOptions &Opts =
1896 M.getContext().getLibraryOptions().get<InstrumentationOptions>();
1901 if (ProfileSampling)
1925 const InstrumentationOptions &Opts =
1926 M.getContext().getLibraryOptions().get<InstrumentationOptions>();
1928 LookupLI, InstrumentationType))
1941 auto BFIEntryCount =
F.getEntryCount();
1942 assert(BFIEntryCount && (*BFIEntryCount > 0) &&
"Invalid BFI Entrycount");
1946 for (
auto &BBI :
F) {
1949 if (!Func.findBBInfo(&BBI))
1952 CountValue = *Func.getBBInfo(&BBI).Count;
1953 BFICountValue = *BFICount;
1957 if (SumCount.isZero())
1961 "Incorrect sum of BFI counts");
1964 double Scale = (SumCount / SumBFICount).convertToDouble();
1965 if (Scale < 1.001 && Scale > 0.999)
1970 if (NewEntryCount == 0)
1973 F.setEntryCount(NewEntryCount);
1976 << NewEntryCount <<
"\n");
1989 bool HotBBOnly = Opts.pgo_verify_hot_bfi;
1993 unsigned BBNum = 0, BBMisMatchNum = 0, NonZeroBBNum = 0;
1994 for (
auto &BBI :
F) {
1995 PGOUseBBInfo *BBInfo = Func.findBBInfo(&BBI);
1999 uint64_t CountValue = BBInfo->Count.value_or(CountValue);
2007 BFICountValue = *BFICount;
2010 bool rawIsHot = CountValue >= HotCountThreshold;
2011 bool BFIIsHot = BFICountValue >= HotCountThreshold;
2013 bool ShowCount =
false;
2014 if (rawIsHot && !BFIIsHot) {
2015 Msg =
"raw-Hot to BFI-nonHot";
2017 }
else if (rawIsCold && BFIIsHot) {
2018 Msg =
"raw-Cold to BFI-Hot";
2024 if ((CountValue < Opts.pgo_verify_bfi_cutoff) &&
2025 (BFICountValue < Opts.pgo_verify_bfi_cutoff))
2027 uint64_t Diff = (BFICountValue >= CountValue)
2028 ? BFICountValue - CountValue
2029 : CountValue - BFICountValue;
2030 if (Diff <= CountValue / 100 * Opts.pgo_verify_bfi_ratio)
2037 F.getSubprogram(), &BBI);
2039 <<
" Count=" <<
ore::NV(
"Count", CountValue)
2040 <<
" BFI_Count=" <<
ore::NV(
"Count", BFICountValue);
2049 F.getSubprogram(), &
F.getEntryBlock())
2050 <<
"In Func " <<
ore::NV(
"Function",
F.getName())
2051 <<
": Num_of_BB=" <<
ore::NV(
"Count", BBNum)
2052 <<
", Num_of_non_zerovalue_BB=" <<
ore::NV(
"Count", NonZeroBBNum)
2053 <<
", Num_of_mis_matching_BB=" <<
ore::NV(
"Count", BBMisMatchNum);
2058 const InstrumentationOptions &Opts,
Module &M,
StringRef ProfileFileName,
2066 auto &Ctx = M.getContext();
2069 ProfileRemappingFileName);
2070 if (
Error E = ReaderOrErr.takeError()) {
2078 std::unique_ptr<IndexedInstrProfReader> PGOReader =
2079 std::move(ReaderOrErr.get());
2085 if (!PGOReader->hasCSIRLevelProfile() && IsCS)
2089 if (!PGOReader->isIRLevelProfile()) {
2091 ProfileFileName.
data(),
"Not an IR level instrumentation profile"));
2094 if (PGOReader->functionEntryOnly()) {
2096 ProfileFileName.
data(),
2097 "Function entry profiles are not yet supported for optimization"));
2104 M.setProfileSummary(PGOReader->getSummary(IsCS).getMD(M.getContext()),
2109 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
2111 std::vector<Function *> HotFunctions;
2112 std::vector<Function *> ColdFunctions;
2116 bool InstrumentFuncEntry =
2117 valueOr(Opts.pgo_instrument_entry, PGOReader->instrEntryBBEnabled());
2118 bool InstrumentLoopEntries =
valueOr(Opts.pgo_instrument_loop_entries,
2119 PGOReader->instrLoopEntriesEnabled());
2121 bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage();
2129 if (!HasSingleByteCoverage) {
2135 PGOUseFunc Func(Opts,
F, &M, TLI, ComdatMembers, BPI, BFI, LI, PSI, IsCS,
2136 InstrumentFuncEntry, InstrumentLoopEntries,
2137 HasSingleByteCoverage);
2138 if (!Func.getRecord(PGOReader.get()))
2140 if (HasSingleByteCoverage) {
2141 Func.populateCoverage();
2149 bool AllZeros =
false;
2150 if (!Func.readCounters(AllZeros, PseudoKind))
2154 if (Func.getProgramMaxCount() != 0)
2155 ColdFunctions.push_back(&
F);
2160 if (
F.hasFnAttribute(Attribute::Cold))
2161 F.removeFnAttr(Attribute::Cold);
2164 F.addFnAttr(Attribute::Hot);
2167 Func.populateCounters();
2168 Func.setBranchWeights();
2169 Func.annotateValueSites();
2170 Func.annotateIrrLoopHeaderWeights();
2171 Func.setBlockUniformityAttribute();
2172 PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();
2173 if (FreqAttr == PGOUseFunc::FFA_Cold)
2174 ColdFunctions.push_back(&
F);
2175 else if (FreqAttr == PGOUseFunc::FFA_Hot)
2176 HotFunctions.push_back(&
F);
2182 std::unique_ptr<BranchProbabilityInfo> NewBPI =
2183 std::make_unique<BranchProbabilityInfo>(
F, CI);
2184 std::unique_ptr<BlockFrequencyInfo> NewBFI =
2185 std::make_unique<BlockFrequencyInfo>(
F, *NewBPI, CI);
2189 dbgs() <<
"pgo-view-counts: " << Func.getFunc().getName() <<
"\n";
2190 NewBFI->print(
dbgs());
2200 ViewGraph(&Func,
Twine(
"PGORawCounts_") + Func.getFunc().getName());
2201 else if (Opts.pgo_view_raw_counts ==
PGOVCT_Text) {
2202 dbgs() <<
"pgo-view-raw-counts: " << Func.getFunc().getName() <<
"\n";
2207 if (Opts.pgo_verify_bfi || Opts.pgo_verify_hot_bfi ||
2208 Opts.pgo_fix_entry_count) {
2214 if (Opts.pgo_fix_entry_count)
2219 if (Opts.pgo_verify_hot_bfi) {
2232 for (
auto &
F : HotFunctions) {
2233 F->addFnAttr(Attribute::InlineHint);
2234 LLVM_DEBUG(
dbgs() <<
"Set inline attribute to function: " <<
F->getName()
2237 for (
auto &
F : ColdFunctions) {
2240 if (
F->hasFnAttribute(Attribute::Hot)) {
2241 auto &Ctx = M.getContext();
2242 std::string
Msg = std::string(
"Function ") +
F->getName().str() +
2243 std::string(
" is annotated as a hot function but"
2244 " the profile is cold");
2249 F->addFnAttr(Attribute::Cold);
2250 LLVM_DEBUG(
dbgs() <<
"Set cold attribute to function: " <<
F->getName()
2257 std::string
Filename, std::string RemappingFilename,
bool IsCS,
2260 ProfileRemappingFileName(
std::
move(RemappingFilename)), IsCS(IsCS),
2284 const InstrumentationOptions &Opts =
2285 M.getContext().getLibraryOptions().get<InstrumentationOptions>();
2286 StringRef ProfileFile = ProfileFileName;
2287 if (!Opts.pgo_test_profile_file.empty())
2288 ProfileFile = Opts.pgo_test_profile_file;
2289 StringRef RemappingFile = ProfileRemappingFileName;
2290 if (!Opts.pgo_test_profile_remapping_file.empty())
2291 RemappingFile = Opts.pgo_test_profile_remapping_file;
2293 LookupBPI, LookupBFI, LookupLI, PSI, IsCS))
2300 if (!
Node->getName().empty())
2301 return Node->getName().str();
2303 std::string SimpleNodeName;
2306 return SimpleNodeName;
2310 uint64_t MaxCount) {
2313 LLVM_DEBUG(
dbgs() <<
"Weight is: ";
for (
const auto &W : Weights) {
2321 const InstrumentationOptions &Opts =
2323 if (Opts.pgo_emit_branch_prob) {
2325 if (BrCondStr.empty())
2329 std::accumulate(Weights.begin(), Weights.end(), (uint64_t)0,
2330 [](uint64_t w1, uint64_t w2) { return w1 + w2; });
2331 uint64_t TotalCount =
2332 std::accumulate(EdgeCounts.
begin(), EdgeCounts.
end(), (uint64_t)0,
2333 [](uint64_t c1, uint64_t c2) { return c1 + c2; });
2337 std::string BranchProbStr;
2340 OS <<
" (total count : " << TotalCount <<
")";
2345 << BrCondStr <<
" is true with probability : " << BranchProbStr;
2364 return &
G->getFunc().front();
2387 return std::string(
G->getFunc().getName());
2395 PGOUseBBInfo *BI = Graph->findBBInfo(
Node);
2397 if (BI && BI->Count)
2398 OS << *BI->Count <<
"\\l";
2402 const InstrumentationOptions &Opts =
2403 Node->getContext().getLibraryOptions().get<InstrumentationOptions>();
2404 if (!Opts.pgo_instr_select)
2411 OS <<
"SELECT : { T = ";
2415 OS <<
"Unknown, F = Unknown }\\l";
2417 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...
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)
This file finds the minimum set of blocks on a CFG that must be instrumented to infer execution cover...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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 constexpr StringLiteral Filename
static void annotateFunctionWithHashMismatch(Function &F, LLVMContext &ctx)
static bool instrumentAllFunctions(const InstrumentationOptions &Opts, 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 bool skipPGOGen(const InstrumentationOptions &Opts, const Function &F)
static void fixFuncEntryCount(PGOUseFunc &Func, CycleInfo &CI, BranchProbabilityInfo &NBPI)
static void populateEHOperandBundle(VPCandidateInfo &Cand, DenseMap< BasicBlock *, ColorVector > &BlockColors, SmallVectorImpl< OperandBundleDef > &OpBundles)
static void collectComdatMembers(const InstrumentationOptions &Opts, Module &M, std::unordered_multimap< Comdat *, GlobalValue * > &ComdatMembers)
static void setupBBInfoEdges(const FuncPGOInstrumentation< PGOUseEdge, PGOUseBBInfo > &FuncInfo)
Set up InEdges/OutEdges for all BBs in the MST.
ValueProfileCollector::CandidateInfo VPCandidateInfo
static bool skipPGOUse(const InstrumentationOptions &Opts, const Function &F)
static uint64_t sumEdgeCount(const ArrayRef< PGOUseEdge * > Edges)
static uint32_t getMaxNumAnnotations(const InstrumentationOptions &Opts, InstrProfValueKind ValueProfKind)
static std::string getSimpleNodeName(const BasicBlock *Node)
static bool isIndirectBrTarget(BasicBlock *BB)
static bool annotateAllFunctions(const InstrumentationOptions &Opts, 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 GlobalVariable * createIRLevelProfileFlagVar(const InstrumentationOptions &Opts, Module &M, PGOInstrumentationType InstrumentationType)
static void verifyFuncBFI(const InstrumentationOptions &Opts, PGOUseFunc &Func, CycleInfo &CI, BranchProbabilityInfo &NBPI, uint64_t HotCountThreshold, uint64_t ColdCountThreshold)
static bool canRenameComdat(const InstrumentationOptions &Opts, Function &F, std::unordered_multimap< Comdat *, GlobalValue * > &ComdatMembers)
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 getFirstNonPHIOrAlloca() const
Returns an iterator to the first instruction in this block that is not a PHINode, a static alloca,...
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) 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.
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 cl::LibraryOptionsContext & getLibraryOptions() const
The library options this context reads in place of their process-wide values.
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.
LLVMContext & getContext() const
All values hold a context through their type.
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.
@ 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.
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.
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 getIRPGOObjectName for LLVM IR instrumentation.
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...
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...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
LLVM_ABI std::string getIRPGOObjectName(const GlobalObject &GO, bool InLTO=false)
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."))
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...
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)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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)
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.
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.
LLVM_ABI bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken=false)
Check if we can safely rename this Comdat function.
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
uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale)
Scale an individual branch count.
constexpr bool valueOr(BoolOrDefault X, bool Default)
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
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."))
LLVM_ABI bool isPGOInstrumentColdFunctionOnly(const cl::LibraryOptionsContext &LibraryOptions)
Return the value of -pgo-instrument-cold-function-only in LibraryOptions.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
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