125#include <unordered_map>
133#define DEBUG_TYPE "pgo-instrumentation"
135STATISTIC(NumOfPGOInstrument,
"Number of edges instrumented.");
136STATISTIC(NumOfPGOSelectInsts,
"Number of select instruction instrumented.");
137STATISTIC(NumOfPGOMemIntrinsics,
"Number of mem intrinsics instrumented.");
140STATISTIC(NumOfPGOSplit,
"Number of critical edge splits.");
141STATISTIC(NumOfPGOFunc,
"Number of functions having valid profile counts.");
142STATISTIC(NumOfPGOMismatch,
"Number of functions having mismatch profile.");
143STATISTIC(NumOfPGOMissing,
"Number of functions without profile.");
144STATISTIC(NumOfPGOICall,
"Number of indirect call value instrumentations.");
145STATISTIC(NumOfCSPGOInstrument,
"Number of edges instrumented in CSPGO.");
147 "Number of select instruction instrumented in CSPGO.");
149 "Number of mem intrinsics instrumented in CSPGO.");
151STATISTIC(NumOfCSPGOBB,
"Number of basic-blocks in CSPGO.");
152STATISTIC(NumOfCSPGOSplit,
"Number of critical edge splits in CSPGO.");
154 "Number of functions having valid profile counts in CSPGO.");
156 "Number of functions having mismatch profile in CSPGO.");
157STATISTIC(NumOfCSPGOMissing,
"Number of functions without profile in CSPGO.");
158STATISTIC(NumCoveredBlocks,
"Number of basic blocks that were executed");
165 cl::desc(
"Specify the path of profile data file. This is"
166 "mainly for test purpose."));
170 cl::desc(
"Specify the path of profile remapping file. This is mainly for "
177 cl::desc(
"Disable Value Profiling"));
183 cl::desc(
"Max number of annotations for a single indirect "
190 cl::desc(
"Max number of preicise value annotations for a single memop"
197 cl::desc(
"Append function hash to the name of COMDAT function to avoid "
198 "function hash mismatch due to the preinliner"));
205 cl::desc(
"Use this option to turn on/off "
206 "warnings about missing profile data for "
213 cl::desc(
"Use this option to turn off/on "
214 "warnings about profile cfg mismatch."));
221 cl::desc(
"The option is used to turn on/off "
222 "warnings about hash mismatch for comdat "
223 "or weak functions."));
229 cl::desc(
"Use this option to turn on/off SELECT "
230 "instruction instrumentation. "));
235 cl::desc(
"A boolean option to show CFG dag or text "
236 "with raw profile counts from "
237 "profile data. See also option "
238 "-pgo-view-counts. To limit graph "
239 "display to only one function, use "
240 "filtering option -view-bfi-func-name."),
248 cl::desc(
"Use this option to turn on/off "
249 "memory intrinsic size profiling."));
254 cl::desc(
"When this option is on, the annotated "
255 "branch probability will be emitted as "
256 "optimization remarks: -{Rpass|"
257 "pass-remarks}=pgo-instrumentation"));
261 cl::desc(
"Force to instrument function entry basicblock."));
266 "Use this option to enable function entry coverage instrumentation."));
269 "pgo-block-coverage",
270 cl::desc(
"Use this option to enable basic block coverage instrumentation"));
274 cl::desc(
"Create a dot file of CFGs with block "
275 "coverage inference information"));
278 "pgo-temporal-instrumentation",
279 cl::desc(
"Use this option to enable temporal instrumentation"));
283 cl::desc(
"Fix function entry count in profile use."));
287 cl::desc(
"Print out the non-match BFI count if a hot raw profile count "
288 "becomes non-hot, or a cold raw profile count becomes hot. "
289 "The print is enabled under -Rpass-analysis=pgo, or "
290 "internal option -pass-remakrs-analysis=pgo."));
294 cl::desc(
"Print out mismatched BFI counts after setting profile metadata "
295 "The print is enabled under -Rpass-analysis=pgo, or "
296 "internal option -pass-remakrs-analysis=pgo."));
300 cl::desc(
"Set the threshold for pgo-verify-bfi: only print out "
301 "mismatched BFI if the difference percentage is greater than "
302 "this value (in percentage)."));
306 cl::desc(
"Set the threshold for pgo-verify-bfi: skip the counts whose "
307 "profile count value is below."));
312 cl::desc(
"Trace the hash of the function with this name."));
316 cl::desc(
"Do not instrument functions smaller than this threshold."));
320 cl::desc(
"Do not instrument functions with the number of critical edges "
321 " greater than this threshold."));
363 return std::string();
368 return std::string();
380 else if (CV->
isOne())
392#define VALUE_PROF_KIND(Enumerator, Value, Descr) Descr,
399 const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
401 uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
403 ProfileVersion |= VARIANT_MASK_CSIR_PROF;
405 ProfileVersion |= VARIANT_MASK_INSTR_ENTRY;
407 ProfileVersion |= VARIANT_MASK_DBG_CORRELATE;
410 VARIANT_MASK_BYTE_COVERAGE | VARIANT_MASK_FUNCTION_ENTRY_ONLY;
412 ProfileVersion |= VARIANT_MASK_BYTE_COVERAGE;
414 ProfileVersion |= VARIANT_MASK_TEMPORAL_PROF;
419 Triple TT(M.getTargetTriple());
420 if (TT.supportsCOMDAT()) {
422 IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName));
424 return IRLevelVersionVariable;
434enum VisitMode { VM_counting, VM_instrument, VM_annotate };
438struct SelectInstVisitor :
public InstVisitor<SelectInstVisitor> {
441 VisitMode
Mode = VM_counting;
442 unsigned *CurCtrIdx =
nullptr;
443 unsigned TotalNumCtrs = 0;
446 PGOUseFunc *UseFunc =
nullptr;
447 bool HasSingleByteCoverage;
449 SelectInstVisitor(
Function &Func,
bool HasSingleByteCoverage)
450 :
F(
Func), HasSingleByteCoverage(HasSingleByteCoverage) {}
452 void countSelects() {
462 void instrumentSelects(
unsigned *Ind,
unsigned TotalNC,
GlobalVariable *FNV,
464 Mode = VM_instrument;
466 TotalNumCtrs = TotalNC;
473 void annotateSelects(PGOUseFunc *UF,
unsigned *Ind) {
488 unsigned getNumOfSelectInsts()
const {
return NSIs; }
500 bool Removed =
false;
501 bool IsCritical =
false;
504 : SrcBB(Src), DestBB(Dest), Weight(
W) {}
507 std::string infoString()
const {
508 return (
Twine(Removed ?
"-" :
" ") + (InMST ?
" " :
"*") +
509 (IsCritical ?
"c" :
" ") +
" W=" +
Twine(Weight))
520 PGOBBInfo(
unsigned IX) : Group(this),
Index(IX) {}
523 std::string infoString()
const {
529template <
class Edge,
class BBInfo>
class FuncPGOInstrumentation {
537 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
541 void computeCFGHash();
542 void renameComdatFunction();
546 std::vector<std::vector<VPCandidateInfo>> ValueSites;
547 SelectInstVisitor SIVisitor;
548 std::string FuncName;
549 std::string DeprecatedFuncName;
558 const std::optional<BlockCoverageInference> BCI;
560 static std::optional<BlockCoverageInference>
561 constructBCI(
Function &Func,
bool HasSingleByteCoverage,
562 bool InstrumentFuncEntry) {
563 if (HasSingleByteCoverage)
570 void getInstrumentBBs(std::vector<BasicBlock *> &InstrumentBBs);
583 void dumpInfo(
StringRef Str =
"")
const {
585 " Hash: " +
Twine(FunctionHash) +
"\t" + Str);
588 FuncPGOInstrumentation(
590 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
593 bool InstrumentFuncEntry =
true,
bool HasSingleByteCoverage =
false)
594 :
F(
Func), IsCS(IsCS), ComdatMembers(ComdatMembers), VPC(
Func, TLI),
595 TLI(TLI), ValueSites(IPVK_Last + 1),
596 SIVisitor(
Func, HasSingleByteCoverage),
597 MST(
F, InstrumentFuncEntry, BPI,
BFI),
598 BCI(constructBCI(
Func, HasSingleByteCoverage, InstrumentFuncEntry)) {
600 BCI->viewBlockCoverageGraph();
602 SIVisitor.countSelects();
603 ValueSites[IPVK_MemOPSize] = VPC.
get(IPVK_MemOPSize);
605 NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
606 NumOfPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
608 ValueSites[IPVK_IndirectCallTarget] = VPC.
get(IPVK_IndirectCallTarget);
610 ValueSites[IPVK_VTableTarget] = VPC.
get(IPVK_VTableTarget);
612 NumOfCSPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
613 NumOfCSPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
620 if (!ComdatMembers.empty())
621 renameComdatFunction();
624 for (
const auto &E : MST.
allEdges()) {
627 IsCS ? NumOfCSPGOEdge++ : NumOfPGOEdge++;
629 IsCS ? NumOfCSPGOInstrument++ : NumOfPGOInstrument++;
642template <
class Edge,
class BBInfo>
643void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
644 std::vector<uint8_t> Indexes;
648 auto BI = findBBInfo(Succ);
652 for (
int J = 0; J < 4; J++)
653 Indexes.push_back((uint8_t)(
Index >> (J * 8)));
660 auto updateJCH = [&JCH](
uint64_t Num) {
665 updateJCH((
uint64_t)SIVisitor.getNumOfSelectInsts());
666 updateJCH((
uint64_t)ValueSites[IPVK_IndirectCallTarget].
size());
669 updateJCH(BCI->getInstrumentedBlocksHash());
679 FunctionHash &= 0x0FFFFFFFFFFFFFFF;
682 LLVM_DEBUG(
dbgs() <<
"Function Hash Computation for " <<
F.getName() <<
":\n"
683 <<
" CRC = " << JC.
getCRC()
684 <<
", Selects = " << SIVisitor.getNumOfSelectInsts()
685 <<
", Edges = " << MST.
numEdges() <<
", ICSites = "
686 << ValueSites[IPVK_IndirectCallTarget].size()
687 <<
", Memops = " << ValueSites[IPVK_MemOPSize].size()
688 <<
", High32 CRC = " << JCH.
getCRC()
689 <<
", Hash = " << FunctionHash <<
"\n";);
692 dbgs() <<
"Funcname=" <<
F.getName() <<
", Hash=" << FunctionHash
693 <<
" in building " <<
F.getParent()->getSourceFileName() <<
"\n";
699 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
711 for (
auto &&CM :
make_range(ComdatMembers.equal_range(
C))) {
712 assert(!isa<GlobalAlias>(CM.second));
713 Function *FM = dyn_cast<Function>(CM.second);
721template <
class Edge,
class BBInfo>
722void FuncPGOInstrumentation<Edge, BBInfo>::renameComdatFunction() {
725 std::string OrigName =
F.getName().str();
726 std::string NewFuncName =
728 F.setName(
Twine(NewFuncName));
730 FuncName =
Twine(FuncName +
"." +
Twine(FunctionHash)).
str();
736 if (!
F.hasComdat()) {
738 NewComdat =
M->getOrInsertComdat(
StringRef(NewFuncName));
740 F.setComdat(NewComdat);
745 Comdat *OrigComdat =
F.getComdat();
746 std::string NewComdatName =
748 NewComdat =
M->getOrInsertComdat(
StringRef(NewComdatName));
751 for (
auto &&CM :
make_range(ComdatMembers.equal_range(OrigComdat))) {
753 cast<Function>(CM.second)->setComdat(NewComdat);
759template <
class Edge,
class BBInfo>
760void FuncPGOInstrumentation<Edge, BBInfo>::getInstrumentBBs(
761 std::vector<BasicBlock *> &InstrumentBBs) {
764 if (BCI->shouldInstrumentBlock(BB))
765 InstrumentBBs.push_back(&BB);
770 std::vector<Edge *> EdgeList;
772 for (
const auto &E : MST.
allEdges())
773 EdgeList.push_back(E.get());
775 for (
auto &E : EdgeList) {
778 InstrumentBBs.push_back(InstrBB);
784template <
class Edge,
class BBInfo>
785BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *E) {
786 if (E->InMST || E->Removed)
792 if (SrcBB ==
nullptr)
794 if (DestBB ==
nullptr)
809 return canInstrument(SrcBB);
811 return canInstrument(DestBB);
820 dbgs() <<
"Fail to split critical edge: not instrument this edge.\n");
825 IsCS ? NumOfCSPGOSplit++ : NumOfPGOSplit++;
827 <<
" --> " << getBBInfo(DestBB).
Index <<
"\n");
829 MST.
addEdge(SrcBB, InstrBB, 0);
831 Edge &NewEdge1 = MST.
addEdge(InstrBB, DestBB, 0);
832 NewEdge1.InMST =
true;
835 return canInstrument(InstrBB);
851 if (!isa<IntrinsicInst>(OrigCall)) {
854 std::optional<OperandBundleUse> ParentFunclet =
862 if (!BlockColors.
empty()) {
863 const ColorVector &CV = BlockColors.
find(OrigCall->getParent())->second;
864 assert(CV.
size() == 1 &&
"non-unique color for block!");
877 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
885 FuncPGOInstrumentation<PGOEdge, PGOBBInfo> FuncInfo(
889 auto Name = FuncInfo.FuncNameVar;
891 FuncInfo.FunctionHash);
893 auto &EntryBB =
F.getEntryBlock();
894 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstInsertionPt());
903 std::vector<BasicBlock *> InstrumentBBs;
904 FuncInfo.getInstrumentBBs(InstrumentBBs);
905 unsigned NumCounters =
906 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
921 for (
auto &Instr : BB)
922 if (
auto *CS = dyn_cast<CallBase>(&Instr)) {
923 if ((CS->getCalledFunction() &&
924 CS->getCalledFunction()->isIntrinsic()) ||
925 dyn_cast<InlineAsm>(CS->getCalledOperand()))
932 Visit([&TotalNrCallsites](
auto *) { ++TotalNrCallsites; });
936 Visit([&](
auto *CB) {
948 auto &EntryBB =
F.getEntryBlock();
949 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstInsertionPt());
958 for (
auto *InstrBB : InstrumentBBs) {
961 "Cannot get the Instrumentation point");
966 ? Intrinsic::instrprof_cover
967 : Intrinsic::instrprof_increment),
972 FuncInfo.SIVisitor.instrumentSelects(&
I, NumCounters, FuncInfo.FuncNameVar,
973 FuncInfo.FunctionHash);
979 NumOfPGOICall += FuncInfo.ValueSites[IPVK_IndirectCallTarget].size();
986 if (
F.hasPersonalityFn() &&
991 for (
uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {
992 unsigned SiteIndex = 0;
998 <<
" site: CallSite Index = " << SiteIndex <<
"\n");
1002 "Cannot get the Instrumentation point");
1004 Value *ToProfile =
nullptr;
1005 if (Cand.V->getType()->isIntegerTy())
1007 else if (Cand.V->getType()->isPointerTy())
1009 assert(ToProfile &&
"value profiling Value is of unexpected type");
1015 {FuncInfo.FuncNameVar, Builder.
getInt64(FuncInfo.FunctionHash),
1025struct PGOUseEdge :
public PGOEdge {
1026 using PGOEdge::PGOEdge;
1028 std::optional<uint64_t> Count;
1034 std::string infoString()
const {
1036 return PGOEdge::infoString();
1037 return (
Twine(PGOEdge::infoString()) +
" Count=" +
Twine(*Count)).str();
1044struct PGOUseBBInfo :
public PGOBBInfo {
1045 std::optional<uint64_t> Count;
1046 int32_t UnknownCountInEdge = 0;
1047 int32_t UnknownCountOutEdge = 0;
1048 DirectEdges InEdges;
1049 DirectEdges OutEdges;
1051 PGOUseBBInfo(
unsigned IX) : PGOBBInfo(IX) {}
1057 std::string infoString()
const {
1059 return PGOBBInfo::infoString();
1060 return (
Twine(PGOBBInfo::infoString()) +
" Count=" +
Twine(*Count)).str();
1064 void addOutEdge(PGOUseEdge *E) {
1065 OutEdges.push_back(E);
1066 UnknownCountOutEdge++;
1070 void addInEdge(PGOUseEdge *E) {
1071 InEdges.push_back(E);
1072 UnknownCountInEdge++;
1081 for (
const auto &E : Edges) {
1095 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
1098 bool HasSingleByteCoverage)
1099 :
F(
Func),
M(Modu),
BFI(BFIin), PSI(PSI),
1100 FuncInfo(
Func, TLI, ComdatMembers,
false, BPI, BFIin, IsCS,
1101 InstrumentFuncEntry, HasSingleByteCoverage),
1102 FreqAttr(FFA_Normal), IsCS(IsCS), VPC(
Func, TLI) {}
1104 void handleInstrProfError(
Error Err,
uint64_t MismatchedFuncSum);
1111 void populateCounters();
1120 void annotateValueSites();
1123 void annotateValueSites(
uint32_t Kind);
1126 void annotateIrrLoopHeaderWeights();
1129 enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };
1132 FuncFreqAttr getFuncFreqAttr()
const {
return FreqAttr; }
1141 PGOUseBBInfo &getBBInfo(
const BasicBlock *BB)
const {
1142 return FuncInfo.getBBInfo(BB);
1146 PGOUseBBInfo *findBBInfo(
const BasicBlock *BB)
const {
1147 return FuncInfo.findBBInfo(BB);
1152 void dumpInfo(
StringRef Str =
"")
const { FuncInfo.dumpInfo(Str); }
1154 uint64_t getProgramMaxCount()
const {
return ProgramMaxCount; }
1163 FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> FuncInfo;
1179 FuncFreqAttr FreqAttr;
1187 bool setInstrumentedCounts(
const std::vector<uint64_t> &CountFromProfile);
1200 FreqAttr = FFA_Cold;
1208 const FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> &FuncInfo) {
1212 for (
const auto &E : FuncInfo.MST.allEdges()) {
1217 PGOUseBBInfo &SrcInfo = FuncInfo.getBBInfo(SrcBB);
1218 PGOUseBBInfo &DestInfo = FuncInfo.getBBInfo(DestBB);
1219 SrcInfo.addOutEdge(E.get());
1220 DestInfo.addInEdge(E.get());
1226bool PGOUseFunc::setInstrumentedCounts(
1227 const std::vector<uint64_t> &CountFromProfile) {
1229 std::vector<BasicBlock *> InstrumentBBs;
1230 FuncInfo.getInstrumentBBs(InstrumentBBs);
1234 unsigned NumCounters =
1235 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
1238 if (NumCounters != CountFromProfile.size()) {
1241 auto *FuncEntry = &*
F.begin();
1246 uint64_t CountValue = CountFromProfile[
I++];
1247 PGOUseBBInfo &
Info = getBBInfo(InstrBB);
1251 if (InstrBB == FuncEntry && CountValue == 0)
1253 Info.setBBInfoCount(CountValue);
1255 ProfileCountSize = CountFromProfile.size();
1259 auto setEdgeCount = [
this](PGOUseEdge *E,
uint64_t Value) ->
void {
1260 E->setEdgeCount(
Value);
1261 this->getBBInfo(E->SrcBB).UnknownCountOutEdge--;
1262 this->getBBInfo(E->DestBB).UnknownCountInEdge--;
1268 for (
const auto &E : FuncInfo.MST.allEdges()) {
1269 if (E->Removed || E->InMST)
1272 PGOUseBBInfo &SrcInfo = getBBInfo(SrcBB);
1276 if (SrcInfo.Count && SrcInfo.OutEdges.size() == 1)
1277 setEdgeCount(E.get(), *SrcInfo.Count);
1280 PGOUseBBInfo &DestInfo = getBBInfo(DestBB);
1283 if (DestInfo.Count && DestInfo.InEdges.size() == 1)
1284 setEdgeCount(E.get(), *DestInfo.Count);
1290 setEdgeCount(E.get(), 0);
1297void PGOUseFunc::setEdgeCount(DirectEdges &Edges,
uint64_t Value) {
1298 for (
auto &E : Edges) {
1301 E->setEdgeCount(
Value);
1303 getBBInfo(E->SrcBB).UnknownCountOutEdge--;
1304 getBBInfo(E->DestBB).UnknownCountInEdge--;
1312 const char MetadataName[] =
"instr_prof_hash_mismatch";
1315 auto *Existing =
F.getMetadata(LLVMContext::MD_annotation);
1317 MDTuple *Tuple = cast<MDTuple>(Existing);
1318 for (
const auto &
N : Tuple->
operands()) {
1319 if (
N.equalsStr(MetadataName))
1328 F.setMetadata(LLVMContext::MD_annotation, MD);
1331void PGOUseFunc::handleInstrProfError(
Error Err,
uint64_t MismatchedFuncSum) {
1333 auto &Ctx =
M->getContext();
1334 auto Err = IPE.
get();
1335 bool SkipWarning =
false;
1337 << FuncInfo.FuncName <<
": ");
1338 if (Err == instrprof_error::unknown_function) {
1339 IsCS ? NumOfCSPGOMissing++ : NumOfPGOMissing++;
1342 }
else if (Err == instrprof_error::hash_mismatch ||
1343 Err == instrprof_error::malformed) {
1344 IsCS ? NumOfCSPGOMismatch++ : NumOfPGOMismatch++;
1350 LLVM_DEBUG(
dbgs() <<
"hash mismatch (hash= " << FuncInfo.FunctionHash
1351 <<
" skip=" << SkipWarning <<
")");
1361 IPE.
message() + std::string(
" ") +
F.getName().str() +
1362 std::string(
" Hash = ") + std::to_string(FuncInfo.FunctionHash) +
1363 std::string(
" up to ") + std::to_string(MismatchedFuncSum) +
1364 std::string(
" count discarded");
1376 auto &Ctx =
M->getContext();
1379 FuncInfo.FuncName, FuncInfo.FunctionHash, FuncInfo.DeprecatedFuncName,
1380 &MismatchedFuncSum);
1382 handleInstrProfError(std::move(E), MismatchedFuncSum);
1385 ProfileRecord = std::move(
Result.get());
1390 std::vector<uint64_t> &CountFromProfile = ProfileRecord.
Counts;
1392 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1396 for (
unsigned I = 0, S = CountFromProfile.size();
I < S;
I++) {
1398 ValueSum += CountFromProfile[
I];
1400 AllZeros = (ValueSum == 0);
1404 getBBInfo(
nullptr).UnknownCountOutEdge = 2;
1405 getBBInfo(
nullptr).UnknownCountInEdge = 2;
1407 if (!setInstrumentedCounts(CountFromProfile)) {
1409 dbgs() <<
"Inconsistent number of counts, skipping this function");
1411 M->getName().data(),
1412 Twine(
"Inconsistent number of counts in ") +
F.getName().str() +
1413 Twine(
": the profile may be stale or there is a function name "
1425 FuncInfo.FuncName, FuncInfo.FunctionHash, FuncInfo.DeprecatedFuncName,
1426 &MismatchedFuncSum);
1427 if (
auto Err =
Result.takeError()) {
1428 handleInstrProfError(std::move(Err), MismatchedFuncSum);
1431 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
1433 std::vector<uint64_t> &CountsFromProfile =
Result.get().Counts;
1437 if (FuncInfo.BCI->shouldInstrumentBlock(BB))
1443 InverseDependencies;
1444 for (
auto &BB :
F) {
1445 for (
auto *Dep : FuncInfo.BCI->getDependencies(BB)) {
1447 InverseDependencies[Dep].
insert(&BB);
1452 std::stack<const BasicBlock *> CoveredBlocksToProcess;
1453 for (
auto &[BB, IsCovered] : Coverage)
1455 CoveredBlocksToProcess.push(BB);
1457 while (!CoveredBlocksToProcess.empty()) {
1458 auto *CoveredBlock = CoveredBlocksToProcess.top();
1459 assert(Coverage[CoveredBlock]);
1460 CoveredBlocksToProcess.pop();
1461 for (
auto *BB : InverseDependencies[CoveredBlock]) {
1466 CoveredBlocksToProcess.push(BB);
1474 F.setEntryCount(Coverage[&
F.getEntryBlock()] ? 10000 : 0);
1475 for (
auto &BB :
F) {
1484 Weights.
push_back((Coverage[Succ] || !Coverage[&BB]) ? 1 : 0);
1485 if (Weights.
size() >= 2)
1490 unsigned NumCorruptCoverage = 0;
1495 auto IsBlockDead = [&](
const BasicBlock &BB) -> std::optional<bool> {
1496 if (
auto C =
BFI.getBlockProfileCount(&BB))
1500 LLVM_DEBUG(
dbgs() <<
"Block Coverage: (Instrumented=*, Covered=X)\n");
1501 for (
auto &BB :
F) {
1502 LLVM_DEBUG(
dbgs() << (FuncInfo.BCI->shouldInstrumentBlock(BB) ?
"* " :
" ")
1503 << (Coverage[&BB] ?
"X " :
" ") <<
" " << BB.getName()
1509 if (Coverage[&BB] == IsBlockDead(BB).value_or(
false)) {
1511 dbgs() <<
"Found inconsistent block covearge for " << BB.getName()
1512 <<
": BCI=" << (Coverage[&BB] ?
"Covered" :
"Dead") <<
" BFI="
1513 << (IsBlockDead(BB).
value() ?
"Dead" :
"Covered") <<
"\n");
1514 ++NumCorruptCoverage;
1520 auto &Ctx =
M->getContext();
1522 M->getName().data(),
1523 Twine(
"Found inconsistent block coverage for function ") +
F.getName() +
1524 " in " +
Twine(NumCorruptCoverage) +
" blocks.",
1528 FuncInfo.BCI->viewBlockCoverageGraph(&Coverage);
1533void PGOUseFunc::populateCounters() {
1534 bool Changes =
true;
1535 unsigned NumPasses = 0;
1543 PGOUseBBInfo *UseBBInfo = findBBInfo(&BB);
1544 if (UseBBInfo ==
nullptr)
1546 if (!UseBBInfo->Count) {
1547 if (UseBBInfo->UnknownCountOutEdge == 0) {
1550 }
else if (UseBBInfo->UnknownCountInEdge == 0) {
1555 if (UseBBInfo->Count) {
1556 if (UseBBInfo->UnknownCountOutEdge == 1) {
1562 if (*UseBBInfo->Count > OutSum)
1563 Total = *UseBBInfo->Count - OutSum;
1564 setEdgeCount(UseBBInfo->OutEdges,
Total);
1567 if (UseBBInfo->UnknownCountInEdge == 1) {
1570 if (*UseBBInfo->Count > InSum)
1571 Total = *UseBBInfo->Count - InSum;
1572 setEdgeCount(UseBBInfo->InEdges,
Total);
1579 LLVM_DEBUG(
dbgs() <<
"Populate counts in " << NumPasses <<
" passes.\n");
1583 for (
auto &BB :
F) {
1584 auto BI = findBBInfo(&BB);
1587 assert(BI->Count &&
"BB count is not valid");
1592 for (
auto &BB :
F) {
1593 auto BI = findBBInfo(&BB);
1596 FuncMaxCount = std::max(FuncMaxCount, *BI->Count);
1606 FuncInfo.SIVisitor.annotateSelects(
this, &CountPosition);
1607 assert(CountPosition == ProfileCountSize);
1609 LLVM_DEBUG(FuncInfo.dumpInfo(
"after reading profile."));
1613void PGOUseFunc::setBranchWeights() {
1615 LLVM_DEBUG(
dbgs() <<
"\nSetting branch weights for func " <<
F.getName()
1616 <<
" IsCS=" << IsCS <<
"\n");
1617 for (
auto &BB :
F) {
1621 if (!(isa<BranchInst>(TI) || isa<SwitchInst>(TI) ||
1622 isa<IndirectBrInst>(TI) || isa<InvokeInst>(TI) ||
1623 isa<CallBrInst>(TI)))
1626 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1627 if (!*BBCountInfo.Count)
1631 unsigned Size = BBCountInfo.OutEdges.size();
1634 for (
unsigned s = 0; s <
Size; s++) {
1635 const PGOUseEdge *E = BBCountInfo.OutEdges[s];
1638 if (DestBB ==
nullptr)
1642 if (EdgeCount > MaxCount)
1643 MaxCount = EdgeCount;
1644 EdgeCounts[SuccNum] = EdgeCount;
1653 auto &Ctx =
M->getContext();
1655 M->getName().data(),
1656 Twine(
"Profile in ") +
F.getName().str() +
1657 Twine(
" partially ignored") +
1658 Twine(
", possibly due to the lack of a return path."),
1666 if (isa<IndirectBrInst>(Pred->getTerminator()))
1672void PGOUseFunc::annotateIrrLoopHeaderWeights() {
1673 LLVM_DEBUG(
dbgs() <<
"\nAnnotating irreducible loop header weights.\n");
1675 for (
auto &BB :
F) {
1681 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
1687void SelectInstVisitor::instrumentOneSelectInst(
SelectInst &SI) {
1691 auto *Step = Builder.CreateZExt(
SI.getCondition(), Int64Ty);
1694 {FuncNameVar, Builder.getInt64(FuncHash), Builder.getInt32(TotalNumCtrs),
1695 Builder.getInt32(*CurCtrIdx), Step});
1699void SelectInstVisitor::annotateOneSelectInst(
SelectInst &SI) {
1700 std::vector<uint64_t> &CountFromProfile = UseFunc->getProfileRecord().Counts;
1701 assert(*CurCtrIdx < CountFromProfile.size() &&
1702 "Out of bound access of counters");
1704 SCounts[0] = CountFromProfile[*CurCtrIdx];
1707 auto BI = UseFunc->findBBInfo(
SI.getParent());
1709 TotalCount = *BI->Count;
1711 SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);
1712 uint64_t MaxCount = std::max(SCounts[0], SCounts[1]);
1717void SelectInstVisitor::visitSelectInst(
SelectInst &SI) {
1721 if (
SI.getCondition()->getType()->isVectorTy())
1729 instrumentOneSelectInst(SI);
1732 annotateOneSelectInst(SI);
1740 if (ValueProfKind == IPVK_MemOPSize)
1742 if (ValueProfKind == llvm::IPVK_VTableTarget)
1748void PGOUseFunc::annotateValueSites() {
1756 annotateValueSites(Kind);
1760void PGOUseFunc::annotateValueSites(
uint32_t Kind) {
1761 assert(Kind <= IPVK_Last);
1762 unsigned ValueSiteIndex = 0;
1775 if (NumValueSites > 0 && Kind == IPVK_VTableTarget &&
1776 NumValueSites != FuncInfo.ValueSites[IPVK_VTableTarget].size() &&
1778 FuncInfo.ValueSites[IPVK_VTableTarget] = VPC.
get(IPVK_VTableTarget);
1779 auto &ValueSites = FuncInfo.ValueSites[
Kind];
1780 if (NumValueSites != ValueSites.size()) {
1781 auto &Ctx =
M->getContext();
1783 M->getName().data(),
1784 Twine(
"Inconsistent number of value sites for ") +
1787 Twine(
"\", possibly due to the use of a stale profile."),
1793 LLVM_DEBUG(
dbgs() <<
"Read one value site profile (kind = " << Kind
1794 <<
"): Index = " << ValueSiteIndex <<
" out of "
1795 << NumValueSites <<
"\n");
1797 *M, *
I.AnnotatedInst, ProfileRecord,
1808 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
1813 ComdatMembers.insert(std::make_pair(
C, &
F));
1815 if (
Comdat *
C = GV.getComdat())
1816 ComdatMembers.insert(std::make_pair(
C, &GV));
1818 if (
Comdat *
C = GA.getComdat())
1819 ComdatMembers.insert(std::make_pair(
C, &GA));
1824 if (
F.isDeclaration())
1829 unsigned NumCriticalEdges = 0;
1830 for (
auto &BB :
F) {
1839 <<
", NumCriticalEdges=" << NumCriticalEdges
1840 <<
" exceed the threshold. Skip PGO.\n");
1850 if (
F.hasFnAttribute(llvm::Attribute::Naked))
1852 if (
F.hasFnAttribute(llvm::Attribute::NoProfile))
1854 if (
F.hasFnAttribute(llvm::Attribute::SkipProfile))
1870 Triple TT(M.getTargetTriple());
1875 Twine(
"VTable value profiling is presently not "
1876 "supported for non-ELF object formats"),
1878 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
1884 auto &TLI = LookupTLI(
F);
1885 auto *BPI = LookupBPI(
F);
1886 auto *BFI = LookupBFI(
F);
1898 if (ProfileSampling)
1932 auto BFIEntryCount =
F.getEntryCount();
1933 assert(BFIEntryCount && (BFIEntryCount->getCount() > 0) &&
1934 "Invalid BFI Entrycount");
1938 for (
auto &BBI :
F) {
1941 if (!Func.findBBInfo(&BBI))
1944 CountValue = *Func.getBBInfo(&BBI).Count;
1945 BFICountValue = *BFICount;
1949 if (SumCount.isZero())
1953 "Incorrect sum of BFI counts");
1956 double Scale = (SumCount / SumBFICount).convertToDouble();
1957 if (Scale < 1.001 && Scale > 0.999)
1962 if (NewEntryCount == 0)
1968 << NewEntryCount <<
"\n");
1985 unsigned BBNum = 0, BBMisMatchNum = 0, NonZeroBBNum = 0;
1986 for (
auto &BBI :
F) {
1990 CountValue = Func.getBBInfo(&BBI).Count.value_or(CountValue);
1997 BFICountValue = *BFICount;
2000 bool rawIsHot = CountValue >= HotCountThreshold;
2001 bool BFIIsHot = BFICountValue >= HotCountThreshold;
2003 bool ShowCount =
false;
2004 if (rawIsHot && !BFIIsHot) {
2005 Msg =
"raw-Hot to BFI-nonHot";
2007 }
else if (rawIsCold && BFIIsHot) {
2008 Msg =
"raw-Cold to BFI-Hot";
2017 uint64_t Diff = (BFICountValue >= CountValue)
2018 ? BFICountValue - CountValue
2019 : CountValue - BFICountValue;
2027 F.getSubprogram(), &BBI);
2029 <<
" Count=" <<
ore::NV(
"Count", CountValue)
2030 <<
" BFI_Count=" <<
ore::NV(
"Count", BFICountValue);
2032 Remark <<
" (" << Msg <<
")";
2039 F.getSubprogram(), &
F.getEntryBlock())
2040 <<
"In Func " <<
ore::NV(
"Function",
F.getName())
2041 <<
": Num_of_BB=" <<
ore::NV(
"Count", BBNum)
2042 <<
", Num_of_non_zerovalue_BB=" <<
ore::NV(
"Count", NonZeroBBNum)
2043 <<
", Num_of_mis_matching_BB=" <<
ore::NV(
"Count", BBMisMatchNum);
2055 auto &Ctx = M.getContext();
2058 ProfileRemappingFileName);
2059 if (
Error E = ReaderOrErr.takeError()) {
2067 std::unique_ptr<IndexedInstrProfReader> PGOReader =
2068 std::move(ReaderOrErr.get());
2074 if (!PGOReader->hasCSIRLevelProfile() && IsCS)
2078 if (!PGOReader->isIRLevelProfile()) {
2080 ProfileFileName.
data(),
"Not an IR level instrumentation profile"));
2083 if (PGOReader->functionEntryOnly()) {
2085 ProfileFileName.
data(),
2086 "Function entry profiles are not yet supported for optimization"));
2092 if (!
G.hasName() || !
G.hasMetadata(LLVMContext::MD_type))
2103 M.setProfileSummary(PGOReader->getSummary(IsCS).getMD(M.getContext()),
2108 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
2110 std::vector<Function *> HotFunctions;
2111 std::vector<Function *> ColdFunctions;
2115 bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled();
2120 bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage();
2124 auto &TLI = LookupTLI(
F);
2125 auto *BPI = LookupBPI(
F);
2126 auto *BFI = LookupBFI(
F);
2127 if (!HasSingleByteCoverage) {
2133 PGOUseFunc Func(
F, &M, TLI, ComdatMembers, BPI, BFI, PSI, IsCS,
2134 InstrumentFuncEntry, HasSingleByteCoverage);
2135 if (HasSingleByteCoverage) {
2136 Func.populateCoverage(PGOReader.get());
2144 bool AllZeros =
false;
2145 if (!Func.readCounters(PGOReader.get(), AllZeros, PseudoKind))
2149 if (Func.getProgramMaxCount() != 0)
2150 ColdFunctions.push_back(&
F);
2155 if (
F.hasFnAttribute(Attribute::Cold))
2156 F.removeFnAttr(Attribute::Cold);
2159 F.addFnAttr(Attribute::Hot);
2162 Func.populateCounters();
2163 Func.setBranchWeights();
2164 Func.annotateValueSites();
2165 Func.annotateIrrLoopHeaderWeights();
2166 PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();
2167 if (FreqAttr == PGOUseFunc::FFA_Cold)
2168 ColdFunctions.push_back(&
F);
2169 else if (FreqAttr == PGOUseFunc::FFA_Hot)
2170 HotFunctions.push_back(&
F);
2175 std::unique_ptr<BranchProbabilityInfo> NewBPI =
2176 std::make_unique<BranchProbabilityInfo>(
F, LI);
2177 std::unique_ptr<BlockFrequencyInfo> NewBFI =
2178 std::make_unique<BlockFrequencyInfo>(
F, *NewBPI, LI);
2182 dbgs() <<
"pgo-view-counts: " << Func.getFunc().getName() <<
"\n";
2183 NewBFI->print(
dbgs());
2193 ViewGraph(&Func,
Twine(
"PGORawCounts_") + Func.getFunc().getName());
2195 dbgs() <<
"pgo-view-raw-counts: " << Func.getFunc().getName() <<
"\n";
2222 for (
auto &
F : HotFunctions) {
2223 F->addFnAttr(Attribute::InlineHint);
2224 LLVM_DEBUG(
dbgs() <<
"Set inline attribute to function: " <<
F->getName()
2227 for (
auto &
F : ColdFunctions) {
2230 if (
F->hasFnAttribute(Attribute::Hot)) {
2231 auto &Ctx = M.getContext();
2232 std::string Msg = std::string(
"Function ") +
F->getName().str() +
2233 std::string(
" is annotated as a hot function but"
2234 " the profile is cold");
2239 F->addFnAttr(Attribute::Cold);
2240 LLVM_DEBUG(
dbgs() <<
"Set cold attribute to function: " <<
F->getName()
2247 std::string Filename, std::string RemappingFilename,
bool IsCS,
2249 : ProfileFileName(
std::
move(Filename)),
2250 ProfileRemappingFileName(
std::
move(RemappingFilename)), IsCS(IsCS),
2276 LookupTLI, LookupBPI, LookupBFI, PSI, IsCS))
2283 if (!
Node->getName().empty())
2284 return Node->getName().str();
2286 std::string SimpleNodeName;
2289 return SimpleNodeName;
2294 assert(MaxCount > 0 &&
"Bad max count");
2297 for (
const auto &ECI : EdgeCounts)
2310 if (BrCondStr.empty())
2322 std::string BranchProbStr;
2325 OS <<
" (total count : " << TotalCount <<
")";
2331 << BrCondStr <<
" is true with probability : " << BranchProbStr;
2350 return &
G->getFunc().front();
2373 return std::string(
G->getFunc().getName());
2381 PGOUseBBInfo *BI = Graph->findBBInfo(Node);
2383 if (BI && BI->Count)
2384 OS << *BI->Count <<
"\\l";
2392 if (!isa<SelectInst>(&
I))
2395 OS <<
"SELECT : { T = ";
2399 OS <<
"Unknown, F = Unknown }\\l";
2401 OS << TC <<
", F = " << FC <<
" }\\l";
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
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...
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)
Module.h This file contains the declarations for the Module class.
static cl::opt< bool > PGOInstrumentEntry("pgo-instrument-entry", cl::init(false), cl::Hidden, cl::desc("Force to instrument function entry basicblock."))
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 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-remakrs-analysis=pgo."))
static void annotateFunctionWithHashMismatch(Function &F, LLVMContext &ctx)
cl::opt< unsigned > MaxNumVTableAnnotations
static cl::opt< bool > PGOTemporalInstrumentation("pgo-temporal-instrumentation", cl::desc("Use this option to enable temporal instrumentation"))
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."))
bool shouldInstrumentForCtxProf()
static void instrumentOneFunc(Function &F, Module *M, TargetLibraryInfo &TLI, BranchProbabilityInfo *BPI, BlockFrequencyInfo *BFI, std::unordered_multimap< Comdat *, GlobalValue * > &ComdatMembers, bool IsCS)
bool isValueProfilingDisabled()
static void populateEHOperandBundle(VPCandidateInfo &Cand, DenseMap< BasicBlock *, ColorVector > &BlockColors, SmallVectorImpl< OperandBundleDef > &OpBundles)
cl::opt< std::string > UseCtxProfile
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 bool InstrumentAllFunctions(Module &M, function_ref< TargetLibraryInfo &(Function &)> LookupTLI, function_ref< BranchProbabilityInfo *(Function &)> LookupBPI, function_ref< BlockFrequencyInfo *(Function &)> LookupBFI, bool IsCS)
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 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 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 bool skipPGOUse(const Function &F)
static bool canRenameComdat(Function &F, std::unordered_multimap< Comdat *, GlobalValue * > &ComdatMembers)
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-remakrs-analysis=pgo."))
static cl::opt< bool > PGOBlockCoverage("pgo-block-coverage", cl::desc("Use this option to enable basic block coverage instrumentation"))
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< unsigned > MaxNumMemOPAnnotations("memop-max-annotations", cl::init(4), cl::Hidden, cl::desc("Max number of preicise value annotations for a single memop" "intrinsic"))
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 GlobalVariable * createIRLevelProfileFlagVar(Module &M, bool IsCS)
static bool isIndirectBrTarget(BasicBlock *BB)
static std::string getBranchCondString(Instruction *TI)
bool shouldInstrumentEntryBB()
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, ProfileSummaryInfo *PSI, bool IsCS)
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 header defines various interfaces for pass management in LLVM.
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isSimple(Instruction *I)
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)
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),...
LLVM Basic Block Representation.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
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...
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...
Value * getCalledOperand() const
Predicate getPredicate() const
Return the predicate for this instruction.
StringRef getName() const
void setSelectionKind(SelectionKind Val)
SelectionKind getSelectionKind() const
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 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.
Tagged union holding either a T or a Error.
Class to represent profile counts.
static 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.
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
BasicBlock::iterator GetInsertPoint() const
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
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.
Expected< InstrProfRecord > getInstrProfRecord(StringRef FuncName, uint64_t FuncHash, StringRef DeprecatedFuncName="", uint64_t *MismatchedFuncSum=nullptr)
Return the NamedInstrProfRecord associated with FuncName and FuncHash.
uint64_t getMaximumFunctionCount(bool UseCS)
Return the maximum of all known function counts.
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)
instrprof_error get() const
std::string message() const override
Return the error message as a string.
unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
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...
void update(ArrayRef< uint8_t > Data)
This is an important class for using LLVM in a threaded context.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
MDString * createString(StringRef Str)
Return the given string as metadata.
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.
static bool isCtxIRPGOInstrEnabled()
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
PGOInstrumentationUse(std::string Filename="", std::string RemappingFilename="", bool IsCS=false, IntrusiveRefCntPtr< vfs::FileSystem > FS=nullptr)
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.
void preserveSet()
Mark an analysis set as preserved.
void preserve()
Mark an analysis as preserved.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Analysis providing profile information.
uint64_t getOrCompColdCountThreshold() const
Returns ColdCountThreshold if set.
void refresh()
If no summary is present, attempt to refresh.
bool isColdCount(uint64_t C) const
Returns true if count C is considered cold.
bool isHotCount(uint64_t C) const
Returns true if count C is considered hot.
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).
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...
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.
void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
static IntegerType * getInt64Ty(LLVMContext &C)
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.
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.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
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)
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.
void setIrrLoopHeaderMetadata(Module *M, Instruction *TI, uint64_t Count)
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.
std::string getPGOFuncName(const Function &F, bool InLTO=false, uint64_t Version=INSTR_PROF_INDEX_VERSION)
Please use getIRPGOFuncName for LLVM IR instrumentation.
void createPGOFuncNameMetadata(Function &F, StringRef PGOFuncName)
Create the PGOFuncName meta data if PGOFuncName is different from function's raw name.
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...
std::string getIRPGOFuncName(const Function &F, bool InLTO=false)
Function::ProfileCount ProfileCount
auto successors(const MachineBasicBlock *BB)
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...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
cl::opt< InstrProfCorrelator::ProfCorrelatorKind > ProfileCorrelate("profile-correlate", cl::desc("Use debug info or binary file to correlate profiles."), cl::init(InstrProfCorrelator::NONE), cl::values(clEnumValN(InstrProfCorrelator::NONE, "", "No profile correlation"), clEnumValN(InstrProfCorrelator::DEBUG_INFO, "debug-info", "Use debug info to correlate"), clEnumValN(InstrProfCorrelator::BINARY, "binary", "Use binary to correlate")))
DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
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="")
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,...
cl::opt< bool > DebugInfoCorrelate
OperandBundleDefT< Value * > OperandBundleDef
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."))
GlobalVariable * createPGOFuncNameVar(Function &F, StringRef PGOFuncName)
Create and return the global variable for function name used in PGO instrumentation.
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)
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...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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)
static uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale)
Scale an individual branch count.
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
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.
bool isCriticalEdge(const Instruction *TI, unsigned SuccNum, bool AllowIdenticalEdges=false)
Return true if the specified edge is a critical edge.
static uint64_t calculateCountScale(uint64_t MaxCount)
Calculate what to divide by to scale counts.
bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken=false)
Check if we can safely rename this Comdat function.
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.
bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
auto predecessors(const MachineBasicBlock *BB)
void setProfMetadata(Module *M, Instruction *TI, ArrayRef< uint64_t > EdgeCounts, uint64_t MaxCount)
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 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)
Profiling information for a single function.
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