126#include <unordered_map>
134#define DEBUG_TYPE "pgo-instrumentation"
136STATISTIC(NumOfPGOInstrument,
"Number of edges instrumented.");
137STATISTIC(NumOfPGOSelectInsts,
"Number of select instruction instrumented.");
138STATISTIC(NumOfPGOMemIntrinsics,
"Number of mem intrinsics instrumented.");
141STATISTIC(NumOfPGOSplit,
"Number of critical edge splits.");
142STATISTIC(NumOfPGOFunc,
"Number of functions having valid profile counts.");
143STATISTIC(NumOfPGOMismatch,
"Number of functions having mismatch profile.");
144STATISTIC(NumOfPGOMissing,
"Number of functions without profile.");
145STATISTIC(NumOfPGOICall,
"Number of indirect call value instrumentations.");
146STATISTIC(NumOfCSPGOInstrument,
"Number of edges instrumented in CSPGO.");
148 "Number of select instruction instrumented in CSPGO.");
150 "Number of mem intrinsics instrumented in CSPGO.");
152STATISTIC(NumOfCSPGOBB,
"Number of basic-blocks in CSPGO.");
153STATISTIC(NumOfCSPGOSplit,
"Number of critical edge splits in CSPGO.");
155 "Number of functions having valid profile counts in CSPGO.");
157 "Number of functions having mismatch profile in CSPGO.");
158STATISTIC(NumOfCSPGOMissing,
"Number of functions without profile in CSPGO.");
159STATISTIC(NumCoveredBlocks,
"Number of basic blocks that were executed");
166 cl::desc(
"Specify the path of profile data file. This is "
167 "mainly for test purpose."));
171 cl::desc(
"Specify the path of profile remapping file. This is mainly for "
178 cl::desc(
"Disable Value Profiling"));
184 cl::desc(
"Max number of annotations for a single indirect "
191 cl::desc(
"Max number of precise value annotations for a single memop"
198 cl::desc(
"Append function hash to the name of COMDAT function to avoid "
199 "function hash mismatch due to the preinliner"));
206 cl::desc(
"Use this option to turn on/off "
207 "warnings about missing profile data for "
214 cl::desc(
"Use this option to turn off/on "
215 "warnings about profile cfg mismatch."));
222 cl::desc(
"The option is used to turn on/off "
223 "warnings about hash mismatch for comdat "
224 "or weak functions."));
230 cl::desc(
"Use this option to turn on/off SELECT "
231 "instruction instrumentation. "));
236 cl::desc(
"A boolean option to show CFG dag or text "
237 "with raw profile counts from "
238 "profile data. See also option "
239 "-pgo-view-counts. To limit graph "
240 "display to only one function, use "
241 "filtering option -view-bfi-func-name."),
249 cl::desc(
"Use this option to turn on/off "
250 "memory intrinsic size profiling."));
255 cl::desc(
"When this option is on, the annotated "
256 "branch probability will be emitted as "
257 "optimization remarks: -{Rpass|"
258 "pass-remarks}=pgo-instrumentation"));
262 cl::desc(
"Force to instrument function entry basicblock."));
267 cl::desc(
"Force to instrument loop entries."));
272 "Use this option to enable function entry coverage instrumentation."));
275 "pgo-block-coverage",
276 cl::desc(
"Use this option to enable basic block coverage instrumentation"));
280 cl::desc(
"Create a dot file of CFGs with block "
281 "coverage inference information"));
284 "pgo-temporal-instrumentation",
285 cl::desc(
"Use this option to enable temporal instrumentation"));
289 cl::desc(
"Fix function entry count in profile use."));
293 cl::desc(
"Print out the non-match BFI count if a hot raw profile count "
294 "becomes non-hot, or a cold raw profile count becomes hot. "
295 "The print is enabled under -Rpass-analysis=pgo, or "
296 "internal option -pass-remarks-analysis=pgo."));
300 cl::desc(
"Print out mismatched BFI counts after setting profile metadata "
301 "The print is enabled under -Rpass-analysis=pgo, or "
302 "internal option -pass-remarks-analysis=pgo."));
306 cl::desc(
"Set the threshold for pgo-verify-bfi: only print out "
307 "mismatched BFI if the difference percentage is greater than "
308 "this value (in percentage)."));
312 cl::desc(
"Set the threshold for pgo-verify-bfi: skip the counts whose "
313 "profile count value is below."));
318 cl::desc(
"Trace the hash of the function with this name."));
322 cl::desc(
"Do not instrument functions smaller than this threshold."));
326 cl::desc(
"Do not instrument functions with the number of critical edges "
327 " greater than this threshold."));
331 cl::desc(
"For cold function instrumentation, skip instrumenting functions "
332 "whose entry count is above the given value."));
336 cl::desc(
"For cold function instrumentation, treat count unknown(e.g. "
337 "unprofiled) functions as cold."));
341 cl::desc(
"Enable cold function only instrumentation."));
345 cl::desc(
"Do not instrument callsites to functions in this list. Intended "
368class FunctionInstrumenter final {
372 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
383 bool isValueProfilingDisabled()
const {
385 InstrumentationType == PGOInstrumentationType::CTXPROF;
388 bool shouldInstrumentEntryBB()
const {
390 InstrumentationType == PGOInstrumentationType::CTXPROF;
396 FunctionInstrumenter(
398 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
402 : M(M),
F(
F), TLI(TLI), ComdatMembers(ComdatMembers), BPI(BPI), BFI(BFI),
403 LI(LI), InstrumentationType(InstrumentationType) {}
414 return std::string();
419 return std::string();
431 else if (CV->
isOne())
442#define VALUE_PROF_KIND(Enumerator, Value, Descr) Descr,
451 const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
453 uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
454 if (InstrumentationType == PGOInstrumentationType::CSFDO)
455 ProfileVersion |= VARIANT_MASK_CSIR_PROF;
457 InstrumentationType == PGOInstrumentationType::CTXPROF)
458 ProfileVersion |= VARIANT_MASK_INSTR_ENTRY;
460 ProfileVersion |= VARIANT_MASK_INSTR_LOOP_ENTRIES;
462 ProfileVersion |= VARIANT_MASK_DBG_CORRELATE;
465 VARIANT_MASK_BYTE_COVERAGE | VARIANT_MASK_FUNCTION_ENTRY_ONLY;
467 ProfileVersion |= VARIANT_MASK_BYTE_COVERAGE;
469 ProfileVersion |= VARIANT_MASK_TEMPORAL_PROF;
475 IRLevelVersionVariable->setVisibility(
478 Triple TT(M.getTargetTriple());
479 if (TT.supportsCOMDAT()) {
481 IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName));
483 return IRLevelVersionVariable;
493enum VisitMode { VM_counting, VM_instrument, VM_annotate };
497struct SelectInstVisitor :
public InstVisitor<SelectInstVisitor> {
500 VisitMode
Mode = VM_counting;
501 unsigned *CurCtrIdx =
nullptr;
502 unsigned TotalNumCtrs = 0;
505 PGOUseFunc *UseFunc =
nullptr;
506 bool HasSingleByteCoverage;
508 SelectInstVisitor(
Function &Func,
bool HasSingleByteCoverage)
509 :
F(
Func), HasSingleByteCoverage(HasSingleByteCoverage) {}
511 void countSelects() {
521 void instrumentSelects(
unsigned *Ind,
unsigned TotalNC,
GlobalValue *FNV,
523 Mode = VM_instrument;
525 TotalNumCtrs = TotalNC;
532 void annotateSelects(PGOUseFunc *UF,
unsigned *Ind) {
547 unsigned getNumOfSelectInsts()
const {
return NSIs; }
559 bool Removed =
false;
560 bool IsCritical =
false;
563 : SrcBB(Src), DestBB(Dest), Weight(
W) {}
566 std::string infoString()
const {
567 return (
Twine(Removed ?
"-" :
" ") + (InMST ?
" " :
"*") +
568 (IsCritical ?
"c" :
" ") +
" W=" +
Twine(Weight))
579 PGOBBInfo(
unsigned IX) : Group(this),
Index(IX) {}
582 std::string infoString()
const {
583 return (
Twine(
"Index=") +
Twine(Index)).str();
588template <
class Edge,
class BBInfo>
class FuncPGOInstrumentation {
596 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
600 void computeCFGHash();
601 void renameComdatFunction();
605 std::vector<std::vector<VPCandidateInfo>> ValueSites;
606 SelectInstVisitor SIVisitor;
607 std::string FuncName;
608 std::string DeprecatedFuncName;
617 const std::optional<BlockCoverageInference> BCI;
619 static std::optional<BlockCoverageInference>
620 constructBCI(
Function &Func,
bool HasSingleByteCoverage,
621 bool InstrumentFuncEntry) {
622 if (HasSingleByteCoverage)
629 void getInstrumentBBs(std::vector<BasicBlock *> &InstrumentBBs);
642 void dumpInfo(
StringRef Str =
"")
const {
644 " Hash: " +
Twine(FunctionHash) +
"\t" + Str);
647 FuncPGOInstrumentation(
649 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
652 bool IsCS =
false,
bool InstrumentFuncEntry =
true,
653 bool InstrumentLoopEntries =
false,
bool HasSingleByteCoverage =
false)
654 :
F(
Func), IsCS(IsCS), ComdatMembers(ComdatMembers), VPC(
Func, TLI),
655 TLI(TLI), ValueSites(IPVK_Last + 1),
656 SIVisitor(
Func, HasSingleByteCoverage),
657 MST(
F, InstrumentFuncEntry, InstrumentLoopEntries, BPI,
BFI, LI),
658 BCI(constructBCI(
Func, HasSingleByteCoverage, InstrumentFuncEntry)) {
660 BCI->viewBlockCoverageGraph();
662 SIVisitor.countSelects();
663 ValueSites[IPVK_MemOPSize] = VPC.
get(IPVK_MemOPSize);
665 NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
666 NumOfPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
668 ValueSites[IPVK_IndirectCallTarget] = VPC.
get(IPVK_IndirectCallTarget);
670 ValueSites[IPVK_VTableTarget] = VPC.
get(IPVK_VTableTarget);
672 NumOfCSPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
673 NumOfCSPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
680 if (!ComdatMembers.empty())
681 renameComdatFunction();
684 for (
const auto &E : MST.
allEdges()) {
687 IsCS ? NumOfCSPGOEdge++ : NumOfPGOEdge++;
689 IsCS ? NumOfCSPGOInstrument++ : NumOfPGOInstrument++;
702template <
class Edge,
class BBInfo>
703void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
704 std::vector<uint8_t> Indexes;
708 auto BI = findBBInfo(Succ);
712 for (
int J = 0; J < 4; J++)
713 Indexes.push_back((
uint8_t)(Index >> (J * 8)));
720 auto updateJCH = [&JCH](
uint64_t Num) {
725 updateJCH((
uint64_t)SIVisitor.getNumOfSelectInsts());
726 updateJCH((
uint64_t)ValueSites[IPVK_IndirectCallTarget].
size());
729 updateJCH(BCI->getInstrumentedBlocksHash());
739 FunctionHash &= 0x0FFFFFFFFFFFFFFF;
742 LLVM_DEBUG(
dbgs() <<
"Function Hash Computation for " <<
F.getName() <<
":\n"
743 <<
" CRC = " << JC.
getCRC()
744 <<
", Selects = " << SIVisitor.getNumOfSelectInsts()
745 <<
", Edges = " << MST.
numEdges() <<
", ICSites = "
746 << ValueSites[IPVK_IndirectCallTarget].size()
747 <<
", Memops = " << ValueSites[IPVK_MemOPSize].size()
748 <<
", High32 CRC = " << JCH.
getCRC()
749 <<
", Hash = " << FunctionHash <<
"\n";);
752 dbgs() <<
"Funcname=" <<
F.getName() <<
", Hash=" << FunctionHash
753 <<
" in building " <<
F.getParent()->getSourceFileName() <<
"\n";
759 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
771 for (
auto &&CM :
make_range(ComdatMembers.equal_range(
C))) {
772 assert(!isa<GlobalAlias>(CM.second));
773 Function *FM = dyn_cast<Function>(CM.second);
781template <
class Edge,
class BBInfo>
782void FuncPGOInstrumentation<Edge, BBInfo>::renameComdatFunction() {
785 std::string OrigName =
F.getName().str();
786 std::string NewFuncName =
788 F.setName(
Twine(NewFuncName));
790 FuncName =
Twine(FuncName +
"." +
Twine(FunctionHash)).
str();
796 if (!
F.hasComdat()) {
798 NewComdat =
M->getOrInsertComdat(
StringRef(NewFuncName));
800 F.setComdat(NewComdat);
805 Comdat *OrigComdat =
F.getComdat();
806 std::string NewComdatName =
808 NewComdat =
M->getOrInsertComdat(
StringRef(NewComdatName));
811 for (
auto &&CM :
make_range(ComdatMembers.equal_range(OrigComdat))) {
813 cast<Function>(CM.second)->setComdat(NewComdat);
819template <
class Edge,
class BBInfo>
820void FuncPGOInstrumentation<Edge, BBInfo>::getInstrumentBBs(
821 std::vector<BasicBlock *> &InstrumentBBs) {
824 if (BCI->shouldInstrumentBlock(BB))
825 InstrumentBBs.push_back(&BB);
830 std::vector<Edge *> EdgeList;
832 for (
const auto &E : MST.
allEdges())
833 EdgeList.push_back(E.get());
835 for (
auto &E : EdgeList) {
838 InstrumentBBs.push_back(InstrBB);
844template <
class Edge,
class BBInfo>
845BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *E) {
846 if (E->InMST || E->Removed)
852 if (SrcBB ==
nullptr)
854 if (DestBB ==
nullptr)
869 return canInstrument(SrcBB);
871 return canInstrument(DestBB);
880 dbgs() <<
"Fail to split critical edge: not instrument this edge.\n");
885 IsCS ? NumOfCSPGOSplit++ : NumOfPGOSplit++;
886 LLVM_DEBUG(
dbgs() <<
"Split critical edge: " << getBBInfo(SrcBB).Index
887 <<
" --> " << getBBInfo(DestBB).Index <<
"\n");
889 MST.
addEdge(SrcBB, InstrBB, 0);
892 NewEdge1.InMST =
true;
895 return canInstrument(InstrBB);
911 if (!isa<IntrinsicInst>(OrigCall)) {
914 std::optional<OperandBundleUse> ParentFunclet =
922 if (!BlockColors.
empty()) {
923 const ColorVector &CV = BlockColors.
find(OrigCall->getParent())->second;
924 assert(CV.
size() == 1 &&
"non-unique color for block!");
926 if (EHPadIt->isEHPad())
934void FunctionInstrumenter::instrument() {
941 const bool IsCtxProf = InstrumentationType == PGOInstrumentationType::CTXPROF;
942 FuncPGOInstrumentation<PGOEdge, PGOBBInfo> FuncInfo(
943 F, TLI, ComdatMembers, !IsCtxProf, BPI, BFI, LI,
944 InstrumentationType == PGOInstrumentationType::CSFDO,
945 shouldInstrumentEntryBB(), shouldInstrumentLoopEntries(),
948 auto *
const Name = IsCtxProf ? cast<GlobalValue>(&
F) : FuncInfo.FuncNameVar;
949 auto *
const CFGHash =
954 Name, PointerType::get(
M.getContext(), 0));
956 auto &EntryBB =
F.getEntryBlock();
957 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstNonPHIOrDbgOrAlloca());
960 Builder.CreateIntrinsic(
961 Intrinsic::instrprof_cover,
962 {NormalizedNamePtr, CFGHash, Builder.getInt32(1), Builder.getInt32(0)});
966 std::vector<BasicBlock *> InstrumentBBs;
967 FuncInfo.getInstrumentBBs(InstrumentBBs);
968 unsigned NumCounters =
969 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
986 for (
auto &Instr : BB)
987 if (
auto *CS = dyn_cast<CallBase>(&Instr)) {
990 if (CS->getCalledFunction() &&
991 SkipCSInstr.contains(CS->getCalledFunction()->getName()))
998 Visit([&TotalNumCallsites](
auto *) { ++TotalNumCallsites; });
1002 Visit([&](
auto *CB) {
1004 Builder.CreateCall(CSIntrinsic,
1005 {
Name, CFGHash, Builder.getInt32(TotalNumCallsites),
1007 CB->getCalledOperand()});
1014 auto &EntryBB =
F.getEntryBlock();
1015 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstNonPHIOrDbgOrAlloca());
1018 Builder.CreateIntrinsic(Intrinsic::instrprof_timestamp,
1019 {NormalizedNamePtr, CFGHash,
1020 Builder.getInt32(NumCounters),
1021 Builder.getInt32(
I)});
1025 for (
auto *InstrBB : InstrumentBBs) {
1027 assert(Builder.GetInsertPoint() != InstrBB->
end() &&
1028 "Cannot get the Instrumentation point");
1032 : Intrinsic::instrprof_increment,
1033 {NormalizedNamePtr, CFGHash,
1034 Builder.getInt32(NumCounters),
1035 Builder.getInt32(
I++)});
1039 FuncInfo.SIVisitor.instrumentSelects(&
I, NumCounters,
Name,
1040 FuncInfo.FunctionHash);
1043 if (isValueProfilingDisabled())
1046 NumOfPGOICall += FuncInfo.ValueSites[IPVK_IndirectCallTarget].size();
1053 if (
F.hasPersonalityFn() &&
1059 unsigned SiteIndex = 0;
1065 <<
" site: CallSite Index = " << SiteIndex <<
"\n");
1068 assert(Builder.GetInsertPoint() != Cand.InsertPt->getParent()->end() &&
1069 "Cannot get the Instrumentation point");
1071 Value *ToProfile =
nullptr;
1072 if (Cand.V->getType()->isIntegerTy())
1073 ToProfile = Builder.CreateZExtOrTrunc(Cand.V, Builder.getInt64Ty());
1074 else if (Cand.V->getType()->isPointerTy())
1075 ToProfile = Builder.CreatePtrToInt(Cand.V, Builder.getInt64Ty());
1076 assert(ToProfile &&
"value profiling Value is of unexpected type");
1079 Name, PointerType::get(
M.getContext(), 0));
1085 Intrinsic::instrprof_value_profile),
1086 {NormalizedNamePtr, Builder.getInt64(FuncInfo.FunctionHash),
1087 ToProfile, Builder.getInt32(Kind), Builder.getInt32(SiteIndex++)},
1096struct PGOUseEdge :
public PGOEdge {
1097 using PGOEdge::PGOEdge;
1099 std::optional<uint64_t> Count;
1105 std::string infoString()
const {
1107 return PGOEdge::infoString();
1108 return (
Twine(PGOEdge::infoString()) +
" Count=" +
Twine(*Count)).str();
1115struct PGOUseBBInfo :
public PGOBBInfo {
1116 std::optional<uint64_t> Count;
1117 int32_t UnknownCountInEdge = 0;
1118 int32_t UnknownCountOutEdge = 0;
1119 DirectEdges InEdges;
1120 DirectEdges OutEdges;
1122 PGOUseBBInfo(
unsigned IX) : PGOBBInfo(IX) {}
1128 std::string infoString()
const {
1130 return PGOBBInfo::infoString();
1131 return (
Twine(PGOBBInfo::infoString()) +
" Count=" +
Twine(*Count)).str();
1135 void addOutEdge(PGOUseEdge *E) {
1136 OutEdges.push_back(E);
1137 UnknownCountOutEdge++;
1141 void addInEdge(PGOUseEdge *E) {
1142 InEdges.push_back(E);
1143 UnknownCountInEdge++;
1152 for (
const auto &E : Edges) {
1166 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
1169 bool InstrumentFuncEntry,
bool InstrumentLoopEntries,
1170 bool HasSingleByteCoverage)
1171 :
F(
Func),
M(Modu),
BFI(BFIin), PSI(PSI),
1172 FuncInfo(
Func, TLI, ComdatMembers,
false, BPI, BFIin, LI, IsCS,
1173 InstrumentFuncEntry, InstrumentLoopEntries,
1174 HasSingleByteCoverage),
1175 FreqAttr(FFA_Normal), IsCS(IsCS), VPC(
Func, TLI) {}
1177 void handleInstrProfError(
Error Err,
uint64_t MismatchedFuncSum);
1185 bool readCounters(
bool &AllZeros,
1189 void populateCounters();
1192 void populateCoverage();
1198 void annotateValueSites();
1201 void annotateValueSites(
uint32_t Kind);
1204 void annotateIrrLoopHeaderWeights();
1207 enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };
1210 FuncFreqAttr getFuncFreqAttr()
const {
return FreqAttr; }
1219 PGOUseBBInfo &getBBInfo(
const BasicBlock *BB)
const {
1220 return FuncInfo.getBBInfo(BB);
1224 PGOUseBBInfo *findBBInfo(
const BasicBlock *BB)
const {
1225 return FuncInfo.findBBInfo(BB);
1230 void dumpInfo(
StringRef Str =
"")
const { FuncInfo.dumpInfo(Str); }
1232 uint64_t getProgramMaxCount()
const {
return ProgramMaxCount; }
1241 FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> FuncInfo;
1257 FuncFreqAttr FreqAttr;
1265 bool setInstrumentedCounts(
const std::vector<uint64_t> &CountFromProfile);
1278 FreqAttr = FFA_Cold;
1286 const FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> &FuncInfo) {
1290 for (
const auto &E : FuncInfo.MST.allEdges()) {
1295 PGOUseBBInfo &SrcInfo = FuncInfo.getBBInfo(SrcBB);
1296 PGOUseBBInfo &DestInfo = FuncInfo.getBBInfo(DestBB);
1297 SrcInfo.addOutEdge(E.get());
1298 DestInfo.addInEdge(E.get());
1304bool PGOUseFunc::setInstrumentedCounts(
1305 const std::vector<uint64_t> &CountFromProfile) {
1307 std::vector<BasicBlock *> InstrumentBBs;
1308 FuncInfo.getInstrumentBBs(InstrumentBBs);
1312 unsigned NumCounters =
1313 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
1316 if (NumCounters != CountFromProfile.size()) {
1319 auto *FuncEntry = &*
F.begin();
1324 uint64_t CountValue = CountFromProfile[
I++];
1325 PGOUseBBInfo &
Info = getBBInfo(InstrBB);
1329 if (InstrBB == FuncEntry && CountValue == 0)
1331 Info.setBBInfoCount(CountValue);
1333 ProfileCountSize = CountFromProfile.size();
1337 auto setEdgeCount = [
this](PGOUseEdge *E,
uint64_t Value) ->
void {
1338 E->setEdgeCount(
Value);
1339 this->getBBInfo(E->SrcBB).UnknownCountOutEdge--;
1340 this->getBBInfo(E->DestBB).UnknownCountInEdge--;
1346 for (
const auto &E : FuncInfo.MST.allEdges()) {
1347 if (E->Removed || E->InMST)
1350 PGOUseBBInfo &SrcInfo = getBBInfo(SrcBB);
1354 if (SrcInfo.Count && SrcInfo.OutEdges.size() == 1)
1355 setEdgeCount(E.get(), *SrcInfo.Count);
1358 PGOUseBBInfo &DestInfo = getBBInfo(DestBB);
1361 if (DestInfo.Count && DestInfo.InEdges.size() == 1)
1362 setEdgeCount(E.get(), *DestInfo.Count);
1368 setEdgeCount(E.get(), 0);
1375void PGOUseFunc::setEdgeCount(DirectEdges &Edges,
uint64_t Value) {
1376 for (
auto &E : Edges) {
1379 E->setEdgeCount(
Value);
1381 getBBInfo(E->SrcBB).UnknownCountOutEdge--;
1382 getBBInfo(E->DestBB).UnknownCountInEdge--;
1390 const char MetadataName[] =
"instr_prof_hash_mismatch";
1393 auto *Existing =
F.getMetadata(LLVMContext::MD_annotation);
1395 MDTuple *Tuple = cast<MDTuple>(Existing);
1396 for (
const auto &
N : Tuple->
operands()) {
1397 if (
N.equalsStr(MetadataName))
1406 F.setMetadata(LLVMContext::MD_annotation, MD);
1409void PGOUseFunc::handleInstrProfError(
Error Err,
uint64_t MismatchedFuncSum) {
1411 auto &Ctx =
M->getContext();
1412 auto Err = IPE.
get();
1413 bool SkipWarning =
false;
1415 << FuncInfo.FuncName <<
": ");
1416 if (Err == instrprof_error::unknown_function) {
1417 IsCS ? NumOfCSPGOMissing++ : NumOfPGOMissing++;
1420 }
else if (Err == instrprof_error::hash_mismatch ||
1421 Err == instrprof_error::malformed) {
1422 IsCS ? NumOfCSPGOMismatch++ : NumOfPGOMismatch++;
1428 LLVM_DEBUG(
dbgs() <<
"hash mismatch (hash= " << FuncInfo.FunctionHash
1429 <<
" skip=" << SkipWarning <<
")");
1439 IPE.
message() + std::string(
" ") +
F.getName().str() +
1440 std::string(
" Hash = ") + std::to_string(FuncInfo.FunctionHash) +
1441 std::string(
" up to ") + std::to_string(MismatchedFuncSum) +
1442 std::string(
" count discarded");
1452 FuncInfo.FuncName, FuncInfo.FunctionHash, FuncInfo.DeprecatedFuncName,
1453 &MismatchedFuncSum);
1455 handleInstrProfError(std::move(E), MismatchedFuncSum);
1458 ProfileRecord = std::move(
Result.get());
1466bool PGOUseFunc::readCounters(
bool &AllZeros,
1468 auto &Ctx =
M->getContext();
1473 std::vector<uint64_t> &CountFromProfile = ProfileRecord.
Counts;
1475 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1479 for (
unsigned I = 0, S = CountFromProfile.size();
I < S;
I++) {
1481 ValueSum += CountFromProfile[
I];
1483 AllZeros = (ValueSum == 0);
1487 getBBInfo(
nullptr).UnknownCountOutEdge = 2;
1488 getBBInfo(
nullptr).UnknownCountInEdge = 2;
1490 if (!setInstrumentedCounts(CountFromProfile)) {
1492 dbgs() <<
"Inconsistent number of counts, skipping this function");
1494 M->getName().data(),
1495 Twine(
"Inconsistent number of counts in ") +
F.getName().str() +
1496 Twine(
": the profile may be stale or there is a function name "
1504void PGOUseFunc::populateCoverage() {
1505 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1511 if (FuncInfo.BCI->shouldInstrumentBlock(BB))
1517 InverseDependencies;
1518 for (
auto &BB :
F) {
1519 for (
auto *Dep : FuncInfo.BCI->getDependencies(BB)) {
1521 InverseDependencies[Dep].
insert(&BB);
1526 std::stack<const BasicBlock *> CoveredBlocksToProcess;
1527 for (
auto &[BB, IsCovered] : Coverage)
1529 CoveredBlocksToProcess.push(BB);
1531 while (!CoveredBlocksToProcess.empty()) {
1532 auto *CoveredBlock = CoveredBlocksToProcess.top();
1533 assert(Coverage[CoveredBlock]);
1534 CoveredBlocksToProcess.pop();
1535 for (
auto *BB : InverseDependencies[CoveredBlock]) {
1541 CoveredBlocksToProcess.push(BB);
1549 F.setEntryCount(Coverage[&
F.getEntryBlock()] ? 10000 : 0);
1550 for (
auto &BB :
F) {
1559 Weights.
push_back((Coverage[Succ] || !Coverage[&BB]) ? 1 : 0);
1560 if (Weights.
size() >= 2)
1565 unsigned NumCorruptCoverage = 0;
1570 auto IsBlockDead = [&](
const BasicBlock &BB) -> std::optional<bool> {
1571 if (
auto C =
BFI.getBlockProfileCount(&BB))
1575 LLVM_DEBUG(
dbgs() <<
"Block Coverage: (Instrumented=*, Covered=X)\n");
1576 for (
auto &BB :
F) {
1577 LLVM_DEBUG(
dbgs() << (FuncInfo.BCI->shouldInstrumentBlock(BB) ?
"* " :
" ")
1578 << (Coverage[&BB] ?
"X " :
" ") <<
" " << BB.getName()
1585 if (Cov == IsBlockDead(BB).value_or(
false)) {
1587 dbgs() <<
"Found inconsistent block covearge for " << BB.getName()
1588 <<
": BCI=" << (Cov ?
"Covered" :
"Dead") <<
" BFI="
1589 << (IsBlockDead(BB).
value() ?
"Dead" :
"Covered") <<
"\n");
1590 ++NumCorruptCoverage;
1596 auto &Ctx =
M->getContext();
1598 M->getName().data(),
1599 Twine(
"Found inconsistent block coverage for function ") +
F.getName() +
1600 " in " +
Twine(NumCorruptCoverage) +
" blocks.",
1604 FuncInfo.BCI->viewBlockCoverageGraph(&Coverage);
1609void PGOUseFunc::populateCounters() {
1610 bool Changes =
true;
1611 unsigned NumPasses = 0;
1619 PGOUseBBInfo *UseBBInfo = findBBInfo(&BB);
1620 if (UseBBInfo ==
nullptr)
1622 if (!UseBBInfo->Count) {
1623 if (UseBBInfo->UnknownCountOutEdge == 0) {
1626 }
else if (UseBBInfo->UnknownCountInEdge == 0) {
1631 if (UseBBInfo->Count) {
1632 if (UseBBInfo->UnknownCountOutEdge == 1) {
1638 if (*UseBBInfo->Count > OutSum)
1639 Total = *UseBBInfo->Count - OutSum;
1640 setEdgeCount(UseBBInfo->OutEdges,
Total);
1643 if (UseBBInfo->UnknownCountInEdge == 1) {
1646 if (*UseBBInfo->Count > InSum)
1647 Total = *UseBBInfo->Count - InSum;
1648 setEdgeCount(UseBBInfo->InEdges,
Total);
1655 LLVM_DEBUG(
dbgs() <<
"Populate counts in " << NumPasses <<
" passes.\n");
1659 for (
auto &BB :
F) {
1660 auto BI = findBBInfo(&BB);
1663 assert(BI->Count &&
"BB count is not valid");
1667 FuncInfo.SIVisitor.annotateSelects(
this, &CountPosition);
1668 assert(CountPosition == ProfileCountSize);
1672 for (
auto &BB :
F) {
1673 auto BI = findBBInfo(&BB);
1676 FuncMaxCount = std::max(FuncMaxCount, *BI->Count);
1685 LLVM_DEBUG(FuncInfo.dumpInfo(
"after reading profile."));
1689void PGOUseFunc::setBranchWeights() {
1691 LLVM_DEBUG(
dbgs() <<
"\nSetting branch weights for func " <<
F.getName()
1692 <<
" IsCS=" << IsCS <<
"\n");
1693 for (
auto &BB :
F) {
1697 if (!(isa<BranchInst>(TI) || isa<SwitchInst>(TI) ||
1698 isa<IndirectBrInst>(TI) || isa<InvokeInst>(TI) ||
1699 isa<CallBrInst>(TI)))
1702 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1703 if (!*BBCountInfo.Count)
1710 unsigned OutEdgesCount = BBCountInfo.OutEdges.size();
1711 unsigned SuccessorCount = BB.getTerminator()->getNumSuccessors();
1712 assert(OutEdgesCount <= SuccessorCount);
1716 for (
unsigned It = 0; It < OutEdgesCount; It++) {
1717 const PGOUseEdge *E = BBCountInfo.OutEdges[It];
1720 if (DestBB ==
nullptr)
1724 if (EdgeCount > MaxCount)
1725 MaxCount = EdgeCount;
1726 EdgeCounts[SuccNum] = EdgeCount;
1735 auto &Ctx =
M->getContext();
1737 M->getName().data(),
1738 Twine(
"Profile in ") +
F.getName().str() +
1739 Twine(
" partially ignored") +
1740 Twine(
", possibly due to the lack of a return path."),
1748 if (isa<IndirectBrInst>(Pred->getTerminator()))
1754void PGOUseFunc::annotateIrrLoopHeaderWeights() {
1755 LLVM_DEBUG(
dbgs() <<
"\nAnnotating irreducible loop header weights.\n");
1757 for (
auto &BB :
F) {
1763 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1769void SelectInstVisitor::instrumentOneSelectInst(
SelectInst &SI) {
1773 auto *Step = Builder.CreateZExt(
SI.getCondition(), Int64Ty);
1774 auto *NormalizedFuncNameVarPtr =
1776 FuncNameVar, PointerType::get(
M->getContext(), 0));
1777 Builder.CreateIntrinsic(Intrinsic::instrprof_increment_step,
1778 {NormalizedFuncNameVarPtr, Builder.getInt64(FuncHash),
1779 Builder.getInt32(TotalNumCtrs),
1780 Builder.getInt32(*CurCtrIdx), Step});
1784void SelectInstVisitor::annotateOneSelectInst(
SelectInst &SI) {
1785 std::vector<uint64_t> &CountFromProfile = UseFunc->getProfileRecord().Counts;
1786 assert(*CurCtrIdx < CountFromProfile.size() &&
1787 "Out of bound access of counters");
1789 SCounts[0] = CountFromProfile[*CurCtrIdx];
1792 auto BI = UseFunc->findBBInfo(
SI.getParent());
1793 if (BI !=
nullptr) {
1794 TotalCount = *BI->Count;
1797 if (TotalCount < SCounts[0])
1798 BI->Count = SCounts[0];
1801 SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);
1802 uint64_t MaxCount = std::max(SCounts[0], SCounts[1]);
1807void SelectInstVisitor::visitSelectInst(
SelectInst &SI) {
1811 if (
SI.getCondition()->getType()->isVectorTy())
1819 instrumentOneSelectInst(SI);
1822 annotateOneSelectInst(SI);
1830 if (ValueProfKind == IPVK_MemOPSize)
1832 if (ValueProfKind == llvm::IPVK_VTableTarget)
1838void PGOUseFunc::annotateValueSites() {
1846 annotateValueSites(Kind);
1850void PGOUseFunc::annotateValueSites(
uint32_t Kind) {
1851 assert(Kind <= IPVK_Last);
1852 unsigned ValueSiteIndex = 0;
1865 if (NumValueSites > 0 && Kind == IPVK_VTableTarget &&
1866 NumValueSites != FuncInfo.ValueSites[IPVK_VTableTarget].size() &&
1868 FuncInfo.ValueSites[IPVK_VTableTarget] = VPC.
get(IPVK_VTableTarget);
1869 auto &ValueSites = FuncInfo.ValueSites[
Kind];
1870 if (NumValueSites != ValueSites.size()) {
1871 auto &Ctx =
M->getContext();
1873 M->getName().data(),
1874 Twine(
"Inconsistent number of value sites for ") +
1877 Twine(
"\", possibly due to the use of a stale profile."),
1883 LLVM_DEBUG(
dbgs() <<
"Read one value site profile (kind = " << Kind
1884 <<
"): Index = " << ValueSiteIndex <<
" out of "
1885 << NumValueSites <<
"\n");
1887 *M, *
I.AnnotatedInst, ProfileRecord,
1898 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
1903 ComdatMembers.insert(std::make_pair(
C, &
F));
1905 if (
Comdat *
C = GV.getComdat())
1906 ComdatMembers.insert(std::make_pair(
C, &GV));
1908 if (
Comdat *
C = GA.getComdat())
1909 ComdatMembers.insert(std::make_pair(
C, &GA));
1914 if (
F.isDeclaration())
1919 unsigned NumCriticalEdges = 0;
1920 for (
auto &BB :
F) {
1929 <<
", NumCriticalEdges=" << NumCriticalEdges
1930 <<
" exceed the threshold. Skip PGO.\n");
1940 if (
F.hasFnAttribute(llvm::Attribute::Naked))
1942 if (
F.hasFnAttribute(llvm::Attribute::NoProfile))
1944 if (
F.hasFnAttribute(llvm::Attribute::SkipProfile))
1949 if (
auto EntryCount =
F.getEntryCount())
1964 if (InstrumentationType == PGOInstrumentationType::FDO)
1967 Triple TT(M.getTargetTriple());
1972 Twine(
"VTable value profiling is presently not "
1973 "supported for non-ELF object formats"),
1975 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
1985 FunctionInstrumenter FI(M,
F, TLI, ComdatMembers, BPI, BFI, LI,
1986 InstrumentationType);
1999 if (ProfileSampling)
2024 InstrumentationType))
2037 auto BFIEntryCount =
F.getEntryCount();
2038 assert(BFIEntryCount && (BFIEntryCount->getCount() > 0) &&
2039 "Invalid BFI Entrycount");
2043 for (
auto &BBI :
F) {
2046 if (!Func.findBBInfo(&BBI))
2049 CountValue = *Func.getBBInfo(&BBI).Count;
2050 BFICountValue = *BFICount;
2054 if (SumCount.isZero())
2058 "Incorrect sum of BFI counts");
2061 double Scale = (SumCount / SumBFICount).convertToDouble();
2062 if (Scale < 1.001 && Scale > 0.999)
2067 if (NewEntryCount == 0)
2073 << NewEntryCount <<
"\n");
2090 unsigned BBNum = 0, BBMisMatchNum = 0, NonZeroBBNum = 0;
2091 for (
auto &BBI :
F) {
2092 PGOUseBBInfo *BBInfo = Func.findBBInfo(&BBI);
2096 uint64_t CountValue = BBInfo->Count.value_or(CountValue);
2104 BFICountValue = *BFICount;
2107 bool rawIsHot = CountValue >= HotCountThreshold;
2108 bool BFIIsHot = BFICountValue >= HotCountThreshold;
2110 bool ShowCount =
false;
2111 if (rawIsHot && !BFIIsHot) {
2112 Msg =
"raw-Hot to BFI-nonHot";
2114 }
else if (rawIsCold && BFIIsHot) {
2115 Msg =
"raw-Cold to BFI-Hot";
2124 uint64_t Diff = (BFICountValue >= CountValue)
2125 ? BFICountValue - CountValue
2126 : CountValue - BFICountValue;
2134 F.getSubprogram(), &BBI);
2136 <<
" Count=" <<
ore::NV(
"Count", CountValue)
2137 <<
" BFI_Count=" <<
ore::NV(
"Count", BFICountValue);
2139 Remark <<
" (" << Msg <<
")";
2146 F.getSubprogram(), &
F.getEntryBlock())
2147 <<
"In Func " <<
ore::NV(
"Function",
F.getName())
2148 <<
": Num_of_BB=" <<
ore::NV(
"Count", BBNum)
2149 <<
", Num_of_non_zerovalue_BB=" <<
ore::NV(
"Count", NonZeroBBNum)
2150 <<
", Num_of_mis_matching_BB=" <<
ore::NV(
"Count", BBMisMatchNum);
2163 auto &Ctx = M.getContext();
2166 ProfileRemappingFileName);
2167 if (
Error E = ReaderOrErr.takeError()) {
2175 std::unique_ptr<IndexedInstrProfReader> PGOReader =
2176 std::move(ReaderOrErr.get());
2182 if (!PGOReader->hasCSIRLevelProfile() && IsCS)
2186 if (!PGOReader->isIRLevelProfile()) {
2188 ProfileFileName.
data(),
"Not an IR level instrumentation profile"));
2191 if (PGOReader->functionEntryOnly()) {
2193 ProfileFileName.
data(),
2194 "Function entry profiles are not yet supported for optimization"));
2200 if (!
G.hasName() || !
G.hasMetadata(LLVMContext::MD_type))
2211 M.setProfileSummary(PGOReader->getSummary(IsCS).getMD(M.getContext()),
2216 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
2218 std::vector<Function *> HotFunctions;
2219 std::vector<Function *> ColdFunctions;
2223 bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled();
2226 bool InstrumentLoopEntries = PGOReader->instrLoopEntriesEnabled();
2230 bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage();
2238 if (!HasSingleByteCoverage) {
2244 PGOUseFunc Func(
F, &M, TLI, ComdatMembers, BPI, BFI, LI, PSI, IsCS,
2245 InstrumentFuncEntry, InstrumentLoopEntries,
2246 HasSingleByteCoverage);
2247 if (!Func.getRecord(PGOReader.get()))
2249 if (HasSingleByteCoverage) {
2250 Func.populateCoverage();
2258 bool AllZeros =
false;
2259 if (!Func.readCounters(AllZeros, PseudoKind))
2263 if (Func.getProgramMaxCount() != 0)
2264 ColdFunctions.push_back(&
F);
2269 if (
F.hasFnAttribute(Attribute::Cold))
2270 F.removeFnAttr(Attribute::Cold);
2273 F.addFnAttr(Attribute::Hot);
2276 Func.populateCounters();
2277 Func.setBranchWeights();
2278 Func.annotateValueSites();
2279 Func.annotateIrrLoopHeaderWeights();
2280 PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();
2281 if (FreqAttr == PGOUseFunc::FFA_Cold)
2282 ColdFunctions.push_back(&
F);
2283 else if (FreqAttr == PGOUseFunc::FFA_Hot)
2284 HotFunctions.push_back(&
F);
2289 std::unique_ptr<BranchProbabilityInfo> NewBPI =
2290 std::make_unique<BranchProbabilityInfo>(
F, LI);
2291 std::unique_ptr<BlockFrequencyInfo> NewBFI =
2292 std::make_unique<BlockFrequencyInfo>(
F, *NewBPI, LI);
2296 dbgs() <<
"pgo-view-counts: " << Func.getFunc().getName() <<
"\n";
2297 NewBFI->print(
dbgs());
2307 ViewGraph(&Func,
Twine(
"PGORawCounts_") + Func.getFunc().getName());
2309 dbgs() <<
"pgo-view-raw-counts: " << Func.getFunc().getName() <<
"\n";
2336 for (
auto &
F : HotFunctions) {
2337 F->addFnAttr(Attribute::InlineHint);
2338 LLVM_DEBUG(
dbgs() <<
"Set inline attribute to function: " <<
F->getName()
2341 for (
auto &
F : ColdFunctions) {
2344 if (
F->hasFnAttribute(Attribute::Hot)) {
2345 auto &Ctx = M.getContext();
2346 std::string Msg = std::string(
"Function ") +
F->getName().str() +
2347 std::string(
" is annotated as a hot function but"
2348 " the profile is cold");
2353 F->addFnAttr(Attribute::Cold);
2354 LLVM_DEBUG(
dbgs() <<
"Set cold attribute to function: " <<
F->getName()
2361 std::string Filename, std::string RemappingFilename,
bool IsCS,
2363 : ProfileFileName(
std::
move(Filename)),
2364 ProfileRemappingFileName(
std::
move(RemappingFilename)), IsCS(IsCS),
2393 LookupTLI, LookupBPI, LookupBFI, LookupLI, PSI,
2401 if (!
Node->getName().empty())
2402 return Node->getName().str();
2404 std::string SimpleNodeName;
2407 return SimpleNodeName;
2424 if (BrCondStr.empty())
2428 std::accumulate(Weights.begin(), Weights.end(), (
uint64_t)0,
2436 std::string BranchProbStr;
2439 OS <<
" (total count : " << TotalCount <<
")";
2444 << BrCondStr <<
" is true with probability : " << BranchProbStr;
2463 return &
G->getFunc().front();
2486 return std::string(
G->getFunc().getName());
2494 PGOUseBBInfo *BI = Graph->findBBInfo(Node);
2496 if (BI && BI->Count)
2497 OS << *BI->Count <<
"\\l";
2505 if (!isa<SelectInst>(&
I))
2508 OS <<
"SELECT : { T = ";
2512 OS <<
"Unknown, F = Unknown }\\l";
2514 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...
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...
Analysis containing CSE Info
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Given that RA is a live value
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.
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 cl::opt< bool > PGOInstrumentEntry("pgo-instrument-entry", cl::init(false), cl::Hidden, cl::desc("Force to instrument function entry basicblock."))
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 cl::opt< bool > PGOFixEntryCount("pgo-fix-entry-count", cl::init(true), cl::Hidden, cl::desc("Fix function entry count in profile use."))
static void fixFuncEntryCount(PGOUseFunc &Func, LoopInfo &LI, BranchProbabilityInfo &NBPI)
static void annotateFunctionWithHashMismatch(Function &F, LLVMContext &ctx)
cl::opt< unsigned > MaxNumVTableAnnotations
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< bool > PGOTemporalInstrumentation("pgo-temporal-instrumentation", cl::desc("Use this option to enable temporal instrumentation"))
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."))
static cl::opt< unsigned > PGOFunctionSizeThreshold("pgo-function-size-threshold", cl::Hidden, cl::desc("Do not instrument functions smaller than this threshold."))
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 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."))
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."))
static void populateEHOperandBundle(VPCandidateInfo &Cand, DenseMap< BasicBlock *, ColorVector > &BlockColors, SmallVectorImpl< OperandBundleDef > &OpBundles)
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. "))
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< 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."))
static void verifyFuncBFI(PGOUseFunc &Func, LoopInfo &LI, BranchProbabilityInfo &NBPI, uint64_t HotCountThreshold, uint64_t ColdCountThreshold)
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 > 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 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."))
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)
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."))
static cl::opt< bool > PGOBlockCoverage("pgo-block-coverage", cl::desc("Use this option to enable basic block coverage instrumentation"))
static cl::opt< bool > PGOInstrumentLoopEntries("pgo-instrument-loop-entries", cl::init(false), cl::Hidden, cl::desc("Force to instrument loop entries."))
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."))
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 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."))
static uint32_t getMaxNumAnnotations(InstrProfValueKind ValueProfKind)
Function::ProfileCount ProfileCount
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"))
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 cl::opt< bool > PGOViewBlockCoverageGraph("pgo-view-block-coverage-graph", cl::desc("Create a dot file of CFGs with block " "coverage inference information"))
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 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)
cl::opt< bool > PGOInstrumentColdFunctionOnly("pgo-instrument-cold-function-only", cl::init(false), cl::Hidden, cl::desc("Enable cold function only instrumentation."))
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 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 bool isSimple(Instruction *I)
std::pair< BasicBlock *, BasicBlock * > Edge
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
StringSet - A set-like wrapper for the StringMap.
Defines the virtual file system interface vfs::FileSystem.
void printAsOperand(OutputBuffer &OB, Prec P=Prec::Default, bool StrictlyWorse=false) const
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Class for arbitrary precision integers.
This templated class represents "all analyses that operate over <a particular IR unit>" (e....
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
LLVM Basic Block Representation.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI const_iterator getFirstNonPHIOrDbgOrAlloca() const
Returns an iterator to the first instruction in this block that is not a PHINode, a debug intrinsic,...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const BasicBlock *BB, bool AllowSynthetic=false) const
Returns the estimated profile count of BB.
Conditional or Unconditional Branch instruction.
bool isConditional() const
Value * getCondition() const
Analysis pass which computes BranchProbabilityInfo.
Analysis providing branch probability information.
An union-find based Minimum Spanning Tree for CFG.
Edge & addEdge(BasicBlock *Src, BasicBlock *Dest, uint64_t W)
const std::vector< std::unique_ptr< Edge > > & allEdges() const
size_t bbInfoSize() const
BBInfo * findBBInfo(const BasicBlock *BB) const
BBInfo & getBBInfo(const BasicBlock *BB) const
void dumpEdges(raw_ostream &OS, const Twine &Message) const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Predicate getPredicate() const
Return the predicate for this instruction.
LLVM_ABI StringRef getName() const
void setSelectionKind(SelectionKind Val)
SelectionKind getSelectionKind() const
static LLVM_ABI Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
This is the shared class of boolean and integer constants.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Diagnostic information for the PGO profiler.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Base class for error info classes.
virtual std::string message() const
Return the error message as a string.
Lightweight error class with error context and mandatory checking.
Class to represent profile counts.
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
@ HiddenVisibility
The GV is hidden.
@ ProtectedVisibility
The GV is protected.
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
This instruction compares its operands according to the predicate given to the constructor.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Reader for the indexed binary instrprof format.
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.
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Base class for instruction visitors.
void visit(Iterator Start, Iterator End)
RetTy visitSelectInst(SelectInst &I)
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.
ArrayRef< MDOperand > operands() const
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 represents the LLVM 'select' instruction.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
StringSet - A wrapper for StringMap that provides set-like functionality.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
TinyPtrVector - This class is specialized for cases where there are normally 0 or 1 element in a vect...
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
Utility analysis that determines what values are worth profiling.
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.
int getNumOccurrences() const
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.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
uint64_t getFuncHash(const FuncRecordTy *Record)
Return the structural hash associated with the function.
void checkExpectAnnotations(Instruction &I, const ArrayRef< uint32_t > ExistingWeights, bool IsFrontend)
checkExpectAnnotations - compares PGO counters to the thresholds used for llvm.expect and warns if th...
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< FuncNode * > Func
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 getIRPGOFuncName for LLVM IR instrumentation.
LLVM_ABI cl::opt< bool > DebugInfoCorrelate
LLVM_ABI void createPGOFuncNameMetadata(Function &F, StringRef PGOFuncName)
Create the PGOFuncName meta data if PGOFuncName is different from function's raw name.
LLVM_ABI unsigned GetSuccessorNumber(const BasicBlock *BB, const BasicBlock *Succ)
Search for the specified successor of basic block BB and return its position in the terminator instru...
LLVM_ABI std::string getIRPGOFuncName(const Function &F, bool InLTO=false)
Function::ProfileCount ProfileCount
auto successors(const MachineBasicBlock *BB)
LLVM_ABI void createProfileSamplingVar(Module &M)
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
constexpr from_range_t from_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
LLVM_ABI void createPGONameMetadata(GlobalObject &GO, StringRef PGOName)
Create the PGOName metadata if a global object's PGO name is different from its mangled name.
cl::opt< bool > PGOWarnMissing
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
LLVM_ABI bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr)
cl::opt< bool > EnableVTableProfileUse("enable-vtable-profile-use", cl::init(false), cl::desc("If ThinLTO and WPD is enabled and this option is true, vtable " "profiles will be used by ICP pass for more efficient indirect " "call sequence. If false, type profiles won't be used."))
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
OperandBundleDefT< Value * > OperandBundleDef
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)
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
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)
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
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.
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
auto predecessors(const MachineBasicBlock *BB)
llvm::cl::opt< llvm::InstrProfCorrelator::ProfCorrelatorKind > ProfileCorrelate
uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale)
Scale an individual branch count.
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."))
SuccIterator< const Instruction, const BasicBlock > const_succ_iterator
cl::opt< bool > NoPGOWarnMismatchComdatWeak
Implement std::hash so that hash_code can be used in STL containers.
static constexpr roundingMode rmNearestTiesToEven
static LLVM_ABI const fltSemantics & IEEEdouble() LLVM_READNONE
DOTGraphTraits(bool isSimple=false)
static std::string getGraphName(const PGOUseFunc *G)
std::string getNodeLabel(const BasicBlock *Node, const PGOUseFunc *Graph)
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
DefaultDOTGraphTraits - This class provides the default implementations of all of the DOTGraphTraits ...
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)
static nodes_iterator nodes_begin(const PGOUseFunc *G)
std::vector< uint64_t > Counts
CountPseudoKind getCountPseudoKind() const
uint32_t getNumValueSites(uint32_t ValueKind) const
Return the number of instrumented sites for ValueKind.
static void setCSFlagInHash(uint64_t &FuncHash)
Instruction * AnnotatedInst