117 #include <unordered_map> 121 using namespace llvm;
124 #define DEBUG_TYPE "pgo-instrumentation" 126 STATISTIC(NumOfPGOInstrument,
"Number of edges instrumented.");
127 STATISTIC(NumOfPGOSelectInsts,
"Number of select instruction instrumented.");
128 STATISTIC(NumOfPGOMemIntrinsics,
"Number of mem intrinsics instrumented.");
129 STATISTIC(NumOfPGOEdge,
"Number of edges.");
130 STATISTIC(NumOfPGOBB,
"Number of basic-blocks.");
131 STATISTIC(NumOfPGOSplit,
"Number of critical edge splits.");
132 STATISTIC(NumOfPGOFunc,
"Number of functions having valid profile counts.");
133 STATISTIC(NumOfPGOMismatch,
"Number of functions having mismatch profile.");
134 STATISTIC(NumOfPGOMissing,
"Number of functions without profile.");
135 STATISTIC(NumOfPGOICall,
"Number of indirect call value instrumentations.");
142 cl::desc(
"Specify the path of profile data file. This is" 143 "mainly for test purpose."));
147 cl::desc(
"Specify the path of profile remapping file. This is mainly for " 154 cl::desc(
"Disable Value Profiling"));
160 cl::desc(
"Max number of annotations for a single indirect " 167 cl::desc(
"Max number of preicise value annotations for a single memop" 174 cl::desc(
"Append function hash to the name of COMDAT function to avoid " 175 "function hash mismatch due to the preinliner"));
181 cl::desc(
"Use this option to turn on/off " 182 "warnings about missing profile data for " 189 cl::desc(
"Use this option to turn off/on " 190 "warnings about profile cfg mismatch."));
198 cl::desc(
"The option is used to turn on/off " 199 "warnings about hash mismatch for comdat " 205 cl::desc(
"Use this option to turn on/off SELECT " 206 "instruction instrumentation. "));
211 cl::desc(
"A boolean option to show CFG dag or text " 212 "with raw profile counts from " 213 "profile data. See also option " 214 "-pgo-view-counts. To limit graph " 215 "display to only one function, use " 216 "filtering option -view-bfi-func-name."),
224 cl::desc(
"Use this option to turn on/off " 225 "memory intrinsic size profiling."));
230 cl::desc(
"When this option is on, the annotated " 231 "branch probability will be emitted as " 232 "optimization remarks: -{Rpass|" 233 "pass-remarks}=pgo-instrumentation"));
248 return std::string();
253 return std::string();
265 else if (CV->
isOne())
283 enum VisitMode { VM_counting, VM_instrument, VM_annotate };
287 struct SelectInstVisitor :
public InstVisitor<SelectInstVisitor> {
291 unsigned *CurCtrIdx =
nullptr;
292 unsigned TotalNumCtrs = 0;
294 uint64_t FuncHash = 0;
295 PGOUseFunc *UseFunc =
nullptr;
297 SelectInstVisitor(
Function &Func) :
F(Func) {}
309 void instrumentSelects(
Function &Func,
unsigned *Ind,
unsigned TotalNC,
311 Mode = VM_instrument;
313 TotalNumCtrs = TotalNC;
320 void annotateSelects(
Function &Func, PGOUseFunc *UF,
unsigned *Ind) {
335 unsigned getNumOfSelectInsts()
const {
return NSIs; }
339 struct MemIntrinsicVisitor :
public InstVisitor<MemIntrinsicVisitor> {
343 unsigned CurCtrId = 0;
344 unsigned TotalNumCtrs = 0;
346 uint64_t FuncHash = 0;
347 PGOUseFunc *UseFunc =
nullptr;
348 std::vector<Instruction *> Candidates;
350 MemIntrinsicVisitor(
Function &Func) :
F(Func) {}
352 void countMemIntrinsics(
Function &Func) {
358 void instrumentMemIntrinsics(
Function &Func,
unsigned TotalNC,
360 Mode = VM_instrument;
361 TotalNumCtrs = TotalNC;
367 std::vector<Instruction *> findMemIntrinsics(
Function &Func) {
380 unsigned getNumOfMemIntrinsics()
const {
return NMemIs; }
383 class PGOInstrumentationGenLegacyPass :
public ModulePass {
387 PGOInstrumentationGenLegacyPass() :
ModulePass(ID) {
392 StringRef getPassName()
const override {
return "PGOInstrumentationGenPass"; }
395 bool runOnModule(
Module &M)
override;
402 class PGOInstrumentationUseLegacyPass :
public ModulePass {
407 PGOInstrumentationUseLegacyPass(std::string Filename =
"")
408 :
ModulePass(ID), ProfileFileName(std::move(Filename)) {
415 StringRef getPassName()
const override {
return "PGOInstrumentationUsePass"; }
418 std::string ProfileFileName;
420 bool runOnModule(
Module &M)
override;
432 "PGO instrumentation.",
false,
false)
439 return new PGOInstrumentationGenLegacyPass();
445 "Read PGO instrumentation profile.",
false,
false)
452 return new PGOInstrumentationUseLegacyPass(Filename.str());
468 bool Removed =
false;
469 bool IsCritical =
false;
472 : SrcBB(Src), DestBB(Dest), Weight(
W) {}
475 const std::string infoString()
const {
476 return (
Twine(Removed ?
"-" :
" ") + (InMST ?
" " :
"*") +
477 (IsCritical ?
"c" :
" ") +
" W=" +
Twine(Weight)).str();
487 BBInfo(
unsigned IX) : Group(
this),
Index(IX) {}
490 const std::string infoString()
const {
491 return (
Twine(
"Index=") +
Twine(Index)).str();
496 template <
class Edge,
class BBInfo>
class FuncPGOInstrumentation {
501 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
503 void computeCFGHash();
504 void renameComdatFunction();
507 std::vector<std::vector<Instruction *>> ValueSites;
508 SelectInstVisitor SIVisitor;
509 MemIntrinsicVisitor MIVisitor;
510 std::string FuncName;
514 uint64_t FunctionHash = 0;
530 void dumpInfo(std::string Str =
"")
const {
532 Twine(FunctionHash) +
"\t" + Str);
535 FuncPGOInstrumentation(
537 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
540 :
F(Func), ComdatMembers(ComdatMembers), ValueSites(IPVK_Last + 1),
541 SIVisitor(Func), MIVisitor(Func), MST(F, BPI,
BFI) {
543 SIVisitor.countSelects(Func);
544 MIVisitor.countMemIntrinsics(Func);
545 NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
546 NumOfPGOMemIntrinsics += MIVisitor.getNumOfMemIntrinsics();
548 ValueSites[IPVK_MemOPSize] = MIVisitor.findMemIntrinsics(Func);
552 if (!ComdatMembers.empty())
553 renameComdatFunction();
556 NumOfPGOBB += MST.
BBInfos.size();
562 NumOfPGOInstrument++;
570 unsigned getNumCounters() {
571 unsigned NumCounters = 0;
572 for (
auto &E : this->MST.
AllEdges) {
573 if (!E->InMST && !E->Removed)
576 return NumCounters + SIVisitor.getNumOfSelectInsts();
584 template <
class Edge,
class BBInfo>
585 void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
586 std::vector<char> Indexes;
592 auto BI = findBBInfo(Succ);
596 for (
int J = 0; J < 4; J++)
597 Indexes.push_back((
char)(Index >> (J * 8)));
601 FunctionHash = (uint64_t)SIVisitor.getNumOfSelectInsts() << 56 |
602 (uint64_t)ValueSites[IPVK_IndirectCallTarget].
size() << 48 |
603 (uint64_t)MST.AllEdges.size() << 32 | JC.
getCRC();
604 LLVM_DEBUG(
dbgs() <<
"Function Hash Computation for " << F.getName() <<
":\n" 605 <<
" CRC = " << JC.
getCRC()
606 <<
", Selects = " << SIVisitor.getNumOfSelectInsts()
607 <<
", Edges = " << MST.AllEdges.size() <<
", ICSites = " 608 << ValueSites[IPVK_IndirectCallTarget].size()
609 <<
", Hash = " << FunctionHash <<
"\n";);
615 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
627 for (
auto &&CM :
make_range(ComdatMembers.equal_range(C))) {
628 if (dyn_cast<GlobalAlias>(CM.second))
638 template <
class Edge,
class BBInfo>
639 void FuncPGOInstrumentation<Edge, BBInfo>::renameComdatFunction() {
642 std::string OrigName =
F.getName().str();
643 std::string NewFuncName =
644 Twine(
F.getName() +
"." +
Twine(FunctionHash)).str();
645 F.setName(
Twine(NewFuncName));
647 FuncName =
Twine(FuncName +
"." +
Twine(FunctionHash)).
str();
653 if (!
F.hasComdat()) {
657 F.setComdat(NewComdat);
662 Comdat *OrigComdat =
F.getComdat();
663 std::string NewComdatName =
668 for (
auto &&CM :
make_range(ComdatMembers.equal_range(OrigComdat))) {
669 if (
GlobalAlias *GA = dyn_cast<GlobalAlias>(CM.second)) {
671 assert(dyn_cast<Function>(GA->getAliasee()->stripPointerCasts()) == &
F);
672 std::string OrigGAName = GA->getName().str();
673 GA->setName(
Twine(GA->getName() +
"." +
Twine(FunctionHash)));
686 template <
class Edge,
class BBInfo>
687 BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *
E) {
688 if (E->InMST || E->Removed)
694 if (SrcBB ==
nullptr)
696 if (DestBB ==
nullptr)
711 <<
" --> " << getBBInfo(DestBB).
Index <<
"\n");
714 assert(InstrBB &&
"Critical edge is not split");
724 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
728 FuncPGOInstrumentation<PGOEdge, BBInfo> FuncInfo(F, ComdatMembers,
true, BPI,
730 unsigned NumCounters = FuncInfo.getNumCounters();
734 for (
auto &E : FuncInfo.MST.AllEdges) {
735 BasicBlock *InstrBB = FuncInfo.getInstrBB(E.get());
740 assert(Builder.GetInsertPoint() != InstrBB->
end() &&
741 "Cannot get the Instrumentation point");
745 Builder.getInt64(FuncInfo.FunctionHash), Builder.getInt32(NumCounters),
746 Builder.getInt32(I++)});
750 FuncInfo.SIVisitor.instrumentSelects(F, &I, NumCounters, FuncInfo.FuncNameVar,
751 FuncInfo.FunctionHash);
757 unsigned NumIndirectCalls = 0;
758 for (
auto &I : FuncInfo.ValueSites[IPVK_IndirectCallTarget]) {
761 LLVM_DEBUG(
dbgs() <<
"Instrument one indirect call: CallSite Index = " 762 << NumIndirectCalls <<
"\n");
765 "Cannot get the Instrumentation point");
769 Builder.
getInt64(FuncInfo.FunctionHash),
771 Builder.
getInt32(IPVK_IndirectCallTarget),
772 Builder.
getInt32(NumIndirectCalls++)});
774 NumOfPGOICall += NumIndirectCalls;
777 FuncInfo.MIVisitor.instrumentMemIntrinsics(
778 F, NumCounters, FuncInfo.FuncNameVar, FuncInfo.FunctionHash);
784 struct PGOUseEdge :
public PGOEdge {
785 bool CountValid =
false;
786 uint64_t CountValue = 0;
789 : PGOEdge(Src, Dest,
W) {}
792 void setEdgeCount(uint64_t
Value) {
798 const std::string infoString()
const {
800 return PGOEdge::infoString();
801 return (
Twine(PGOEdge::infoString()) +
" Count=" +
Twine(CountValue))
809 struct UseBBInfo :
public BBInfo {
810 uint64_t CountValue = 0;
812 int32_t UnknownCountInEdge = 0;
813 int32_t UnknownCountOutEdge = 0;
815 DirectEdges OutEdges;
817 UseBBInfo(
unsigned IX) : BBInfo(IX), CountValid(
false) {}
819 UseBBInfo(
unsigned IX, uint64_t
C)
820 : BBInfo(IX), CountValue(C), CountValid(
true) {}
823 void setBBInfoCount(uint64_t
Value) {
829 const std::string infoString()
const {
831 return BBInfo::infoString();
832 return (
Twine(BBInfo::infoString()) +
" Count=" +
Twine(CountValue)).str();
841 for (
auto &E : Edges) {
844 Total += E->CountValue;
854 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
857 :
F(Func), M(Modu),
BFI(BFIin),
858 FuncInfo(Func, ComdatMembers,
false, BPI, BFIin),
859 FreqAttr(FFA_Normal) {}
865 void populateCounters();
871 void annotateValueSites();
877 void annotateIrrLoopHeaderWeights();
880 enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };
883 FuncFreqAttr getFuncFreqAttr()
const {
return FreqAttr; }
886 uint64_t getFuncHash()
const {
return FuncInfo.FunctionHash; }
892 UseBBInfo &getBBInfo(
const BasicBlock *BB)
const {
893 return FuncInfo.getBBInfo(BB);
897 UseBBInfo *findBBInfo(
const BasicBlock *BB)
const {
898 return FuncInfo.findBBInfo(BB);
903 void dumpInfo(std::string Str =
"")
const {
904 FuncInfo.dumpInfo(Str);
907 uint64_t getProgramMaxCount()
const {
return ProgramMaxCount; }
914 FuncPGOInstrumentation<PGOUseEdge, UseBBInfo> FuncInfo;
918 uint64_t ProgramMaxCount;
930 FuncFreqAttr FreqAttr;
933 void setInstrumentedCounts(
const std::vector<uint64_t> &CountFromProfile);
937 void setEdgeCount(DirectEdges &Edges, uint64_t
Value);
940 const std::string getFuncName()
const {
return FuncInfo.FuncName; }
945 void markFunctionAttributes(uint64_t EntryCount, uint64_t MaxCount) {
946 if (ProgramMaxCount == 0)
952 if (EntryCount >= HotFunctionThreshold.
scale(ProgramMaxCount))
954 else if (MaxCount <= ColdFunctionThreshold.
scale(ProgramMaxCount))
963 void PGOUseFunc::setInstrumentedCounts(
964 const std::vector<uint64_t> &CountFromProfile) {
965 assert(FuncInfo.getNumCounters() == CountFromProfile.size());
967 std::vector<PGOUseEdge *> WorkList;
968 for (
auto &E : FuncInfo.MST.AllEdges)
969 WorkList.push_back(E.get());
972 for (
auto &E : WorkList) {
976 uint64_t CountValue = CountFromProfile[I++];
978 getBBInfo(InstrBB).setBBInfoCount(CountValue);
979 E->setEdgeCount(CountValue);
987 PGOUseEdge &NewEdge = FuncInfo.MST.addEdge(SrcBB, InstrBB, 0);
988 NewEdge.setEdgeCount(CountValue);
990 PGOUseEdge &NewEdge1 = FuncInfo.MST.addEdge(InstrBB, DestBB, 0);
991 NewEdge1.setEdgeCount(CountValue);
992 NewEdge1.InMST =
true;
993 getBBInfo(InstrBB).setBBInfoCount(CountValue);
995 ProfileCountSize = CountFromProfile.size();
1001 void PGOUseFunc::setEdgeCount(DirectEdges &Edges, uint64_t
Value) {
1002 for (
auto &E : Edges) {
1005 E->setEdgeCount(Value);
1007 getBBInfo(E->SrcBB).UnknownCountOutEdge--;
1008 getBBInfo(E->DestBB).UnknownCountInEdge--;
1018 auto &Ctx = M->getContext();
1023 auto Err = IPE.
get();
1024 bool SkipWarning =
false;
1041 std::string Msg = IPE.
message() + std::string(
" ") +
F.getName().str();
1047 ProfileRecord = std::move(Result.
get());
1048 std::vector<uint64_t> &CountFromProfile = ProfileRecord.Counts;
1052 uint64_t ValueSum = 0;
1053 for (
unsigned I = 0, S = CountFromProfile.size();
I < S;
I++) {
1055 ValueSum += CountFromProfile[
I];
1057 AllZeros = (ValueSum == 0);
1061 getBBInfo(
nullptr).UnknownCountOutEdge = 2;
1062 getBBInfo(
nullptr).UnknownCountInEdge = 2;
1064 setInstrumentedCounts(CountFromProfile);
1071 void PGOUseFunc::populateCounters() {
1073 for (
auto &E : FuncInfo.MST.AllEdges) {
1079 UseBBInfo &SrcInfo = getBBInfo(SrcBB);
1080 UseBBInfo &DestInfo = getBBInfo(DestBB);
1081 SrcInfo.OutEdges.push_back(E.get());
1082 DestInfo.InEdges.push_back(E.get());
1083 SrcInfo.UnknownCountOutEdge++;
1084 DestInfo.UnknownCountInEdge++;
1088 DestInfo.UnknownCountInEdge--;
1089 SrcInfo.UnknownCountOutEdge--;
1092 bool Changes =
true;
1093 unsigned NumPasses = 0;
1101 UseBBInfo *Count = findBBInfo(&BB);
1102 if (Count ==
nullptr)
1104 if (!Count->CountValid) {
1105 if (Count->UnknownCountOutEdge == 0) {
1107 Count->CountValid =
true;
1109 }
else if (Count->UnknownCountInEdge == 0) {
1111 Count->CountValid =
true;
1115 if (Count->CountValid) {
1116 if (Count->UnknownCountOutEdge == 1) {
1122 if (Count->CountValue > OutSum)
1123 Total = Count->CountValue - OutSum;
1124 setEdgeCount(Count->OutEdges, Total);
1127 if (Count->UnknownCountInEdge == 1) {
1130 if (Count->CountValue > InSum)
1131 Total = Count->CountValue - InSum;
1132 setEdgeCount(Count->InEdges, Total);
1139 LLVM_DEBUG(
dbgs() <<
"Populate counts in " << NumPasses <<
" passes.\n");
1142 for (
auto &BB :
F) {
1143 auto BI = findBBInfo(&BB);
1146 assert(BI->CountValid &&
"BB count is not valid");
1149 uint64_t FuncEntryCount = getBBInfo(&*F.begin()).CountValue;
1151 uint64_t FuncMaxCount = FuncEntryCount;
1152 for (
auto &BB : F) {
1153 auto BI = findBBInfo(&BB);
1156 FuncMaxCount =
std::max(FuncMaxCount, BI->CountValue);
1158 markFunctionAttributes(FuncEntryCount, FuncMaxCount);
1161 FuncInfo.SIVisitor.annotateSelects(F,
this, &CountPosition);
1162 assert(CountPosition == ProfileCountSize);
1164 LLVM_DEBUG(FuncInfo.dumpInfo(
"after reading profile."));
1171 for (
auto &BB :
F) {
1175 if (!(isa<BranchInst>(TI) || isa<SwitchInst>(TI) ||
1176 isa<IndirectBrInst>(TI)))
1178 if (getBBInfo(&BB).CountValue == 0)
1182 const UseBBInfo &BBCountInfo = getBBInfo(&BB);
1183 unsigned Size = BBCountInfo.OutEdges.size();
1185 uint64_t MaxCount = 0;
1186 for (
unsigned s = 0; s <
Size; s++) {
1187 const PGOUseEdge *E = BBCountInfo.OutEdges[s];
1190 if (DestBB ==
nullptr)
1193 uint64_t EdgeCount = E->CountValue;
1194 if (EdgeCount > MaxCount)
1195 MaxCount = EdgeCount;
1196 EdgeCounts[SuccNum] = EdgeCount;
1204 if (isa<IndirectBrInst>((*PI)->getTerminator()))
1210 void PGOUseFunc::annotateIrrLoopHeaderWeights() {
1211 LLVM_DEBUG(
dbgs() <<
"\nAnnotating irreducible loop header weights.\n");
1213 for (
auto &BB :
F) {
1219 const UseBBInfo &BBCountInfo = getBBInfo(&BB);
1225 void SelectInstVisitor::instrumentOneSelectInst(
SelectInst &
SI) {
1235 Builder.
getInt32(*CurCtrIdx), Step});
1239 void SelectInstVisitor::annotateOneSelectInst(
SelectInst &SI) {
1240 std::vector<uint64_t> &CountFromProfile = UseFunc->getProfileRecord().Counts;
1241 assert(*CurCtrIdx < CountFromProfile.size() &&
1242 "Out of bound access of counters");
1243 uint64_t SCounts[2];
1244 SCounts[0] = CountFromProfile[*CurCtrIdx];
1246 uint64_t TotalCount = 0;
1247 auto BI = UseFunc->findBBInfo(SI.
getParent());
1249 TotalCount = BI->CountValue;
1251 SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);
1252 uint64_t MaxCount =
std::max(SCounts[0], SCounts[1]);
1257 void SelectInstVisitor::visitSelectInst(
SelectInst &SI) {
1269 instrumentOneSelectInst(SI);
1272 annotateOneSelectInst(SI);
1279 void MemIntrinsicVisitor::instrumentOneMemIntrinsic(
MemIntrinsic &
MI) {
1285 assert(!dyn_cast<ConstantInt>(Length));
1294 void MemIntrinsicVisitor::visitMemIntrinsic(
MemIntrinsic &MI) {
1299 if (dyn_cast<ConstantInt>(Length))
1307 instrumentOneMemIntrinsic(MI);
1310 Candidates.push_back(&MI);
1317 void PGOUseFunc::annotateValueSites() {
1325 annotateValueSites(
Kind);
1330 unsigned ValueSiteIndex = 0;
1331 auto &ValueSites = FuncInfo.ValueSites[
Kind];
1332 unsigned NumValueSites = ProfileRecord.getNumValueSites(Kind);
1333 if (NumValueSites != ValueSites.size()) {
1334 auto &Ctx = M->getContext();
1336 M->getName().data(),
1337 Twine(
"Inconsistent number of value sites for kind = ") +
Twine(Kind) +
1338 " in " +
F.getName().str(),
1343 for (
auto &
I : ValueSites) {
1344 LLVM_DEBUG(
dbgs() <<
"Read one value site profile (kind = " << Kind
1345 <<
"): Index = " << ValueSiteIndex <<
" out of " 1346 << NumValueSites <<
"\n");
1348 static_cast<InstrProfValueKind>(Kind), ValueSiteIndex,
1359 uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
1363 INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
1366 if (!TT.supportsCOMDAT())
1370 StringRef(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR))));
1377 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
1382 ComdatMembers.insert(std::make_pair(
C, &
F));
1384 if (
Comdat *
C = GV.getComdat())
1385 ComdatMembers.insert(std::make_pair(
C, &GV));
1387 if (
Comdat *
C = GA.getComdat())
1388 ComdatMembers.insert(std::make_pair(
C, &GA));
1395 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
1399 if (
F.isDeclaration())
1401 auto *BPI = LookupBPI(
F);
1402 auto *
BFI = LookupBFI(
F);
1408 bool PGOInstrumentationGenLegacyPass::runOnModule(
Module &M) {
1413 return &this->getAnalysis<BranchProbabilityInfoWrapperPass>(
F).getBPI();
1416 return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(
F).getBFI();
1447 if (
Error E = ReaderOrErr.takeError()) {
1455 std::unique_ptr<IndexedInstrProfReader> PGOReader =
1456 std::move(ReaderOrErr.get());
1463 if (!PGOReader->isIRLevelProfile()) {
1465 ProfileFileName.
data(),
"Not an IR level instrumentation profile"));
1469 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
1471 std::vector<Function *> HotFunctions;
1472 std::vector<Function *> ColdFunctions;
1474 if (
F.isDeclaration())
1476 auto *BPI = LookupBPI(
F);
1477 auto *
BFI = LookupBFI(
F);
1481 PGOUseFunc Func(
F, &M, ComdatMembers, BPI,
BFI);
1482 bool AllZeros =
false;
1483 if (!Func.readCounters(PGOReader.get(), AllZeros))
1487 if (Func.getProgramMaxCount() != 0)
1488 ColdFunctions.push_back(&
F);
1491 Func.populateCounters();
1492 Func.setBranchWeights();
1493 Func.annotateValueSites();
1494 Func.annotateIrrLoopHeaderWeights();
1495 PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();
1496 if (FreqAttr == PGOUseFunc::FFA_Cold)
1497 ColdFunctions.push_back(&
F);
1498 else if (FreqAttr == PGOUseFunc::FFA_Hot)
1499 HotFunctions.push_back(&
F);
1504 std::unique_ptr<BranchProbabilityInfo> NewBPI =
1505 llvm::make_unique<BranchProbabilityInfo>(
F, LI);
1506 std::unique_ptr<BlockFrequencyInfo> NewBFI =
1507 llvm::make_unique<BlockFrequencyInfo>(
F, *NewBPI, LI);
1511 dbgs() <<
"pgo-view-counts: " << Func.getFunc().getName() <<
"\n";
1512 NewBFI->print(
dbgs());
1522 ViewGraph(&Func,
Twine(
"PGORawCounts_") + Func.getFunc().getName());
1524 dbgs() <<
"pgo-view-raw-counts: " << Func.getFunc().getName() <<
"\n";
1529 M.setProfileSummary(PGOReader->getSummary().getMD(M.getContext()));
1534 for (
auto &
F : HotFunctions) {
1536 LLVM_DEBUG(
dbgs() <<
"Set inline attribute to function: " <<
F->getName()
1539 for (
auto &
F : ColdFunctions) {
1541 LLVM_DEBUG(
dbgs() <<
"Set cold attribute to function: " <<
F->getName()
1548 std::string RemappingFilename)
1549 : ProfileFileName(
std::move(Filename)),
1550 ProfileRemappingFileName(
std::move(RemappingFilename)) {
1570 LookupBPI, LookupBFI))
1576 bool PGOInstrumentationUseLegacyPass::runOnModule(
Module &M) {
1581 return &this->getAnalysis<BranchProbabilityInfoWrapperPass>(
F).getBPI();
1584 return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(
F).getBFI();
1594 std::string SimpleNodeName;
1602 uint64_t MaxCount) {
1604 assert(MaxCount > 0 &&
"Bad max count");
1607 for (
const auto &ECI : EdgeCounts)
1617 if (BrCondStr.empty())
1621 std::accumulate(Weights.begin(), Weights.end(), (uint64_t)0,
1622 [](uint64_t w1, uint64_t w2) {
return w1 + w2; });
1623 uint64_t TotalCount =
1624 std::accumulate(EdgeCounts.begin(), EdgeCounts.end(), (uint64_t)0,
1625 [](uint64_t c1, uint64_t c2) {
return c1 + c2; });
1629 std::string BranchProbStr;
1632 OS <<
" (total count : " << TotalCount <<
")";
1638 << BrCondStr <<
" is true with probability : " << BranchProbStr;
1648 MDB.createIrrLoopHeaderWeight(Count));
1657 return &G->getFunc().front();
1680 return G->getFunc().getName();
1688 UseBBInfo *BI = Graph->findBBInfo(Node);
1690 if (BI && BI->CountValid)
1691 OS << BI->CountValue <<
"\\l";
1698 for (
auto BI = Node->
begin(); BI != Node->
end(); ++BI) {
1700 if (!isa<SelectInst>(
I))
1703 OS <<
"SELECT : { T = ";
1705 bool HasProf =
I->extractProfMetadata(TC, FC);
1707 OS <<
"Unknown, F = Unknown }\\l";
1709 OS << TC <<
", F = " << FC <<
" }\\l";
static uint64_t sumEdgeCount(const ArrayRef< PGOUseEdge *> Edges)
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
void setProfMetadata(Module *M, Instruction *TI, ArrayRef< uint64_t > EdgeCounts, uint64_t MaxCount)
ModulePass * createPGOInstrumentationGenLegacyPass()
static cl::opt< bool > NoPGOWarnMismatch("no-pgo-warn-mismatch", cl::init(false), cl::Hidden, cl::desc("Use this option to turn off/on " "warnings about profile cfg mismatch."))
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
Base class for instruction visitors.
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
static cl::opt< bool > PGOWarnMissing("pgo-warn-missing-function", cl::init(false), cl::Hidden, cl::desc("Use this option to turn on/off " "warnings about missing profile data for " "functions."))
A Module instance is used to store all the information related to an LLVM module. ...
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
static ChildIteratorType child_begin(const NodeRef N)
std::vector< std::unique_ptr< Edge > > AllEdges
Diagnostic information for the PGO profiler.
Available for inspection, not emission.
void push_back(const T &Elt)
std::string getNodeLabel(const BasicBlock *Node, const PGOUseFunc *Graph)
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken=false)
Check if we can safely rename this Comdat function.
PGOInstrumentationUse(std::string Filename="", std::string RemappingFilename="")
An efficient, type-erasing, non-owning reference to a callable.
INITIALIZE_PASS_BEGIN(PGOInstrumentationGenLegacyPass, "pgo-instr-gen", "PGO instrumentation.", false, false) INITIALIZE_PASS_END(PGOInstrumentationGenLegacyPass
This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM...
virtual std::string message() const
Return the error message as a string.
Externally visible function.
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."))
uint64_t getMaximumFunctionCount()
Return the maximum of all known function counts.
STATISTIC(NumFunctions, "Total number of functions")
static IntegerType * getInt64Ty(LLVMContext &C)
Value * getCondition() const
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...
bool isVectorTy() const
True if this is an instance of VectorType.
Error takeError()
Take ownership of the stored error.
SuccIterator< const Instruction, const BasicBlock > succ_const_iterator
Value * getLength() const
Base class for error info classes.
An union-find based Minimum Spanning Tree for CFG.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
*ViewGraph Emit a dot run run gv on the postscript *then cleanup For use from the debugger *void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)
Function::ProfileCount ProfileCount
iterator begin()
Instruction iterator methods.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
This class represents the LLVM 'select' instruction.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
LLVMContext & getContext() const
Get the global data context.
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."))
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
This file contains the simple types necessary to represent the attributes associated with functions a...
Legacy analysis pass which computes BlockFrequencyInfo.
static std::string getGraphName(const PGOUseFunc *G)
VisitMode
The select instruction visitor plays three roles specified by the mode.
Tagged union holding either a T or a Error.
This file implements a class to represent arbitrary precision integral constant values and operations...
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
static bool isSimple(Instruction *I)
Analysis pass which computes BranchProbabilityInfo.
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
ValTy * getCalledValue() const
Return the pointer to function that is being called.
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
This file provides the interface for IR based instrumentation passes ( (profile-gen, and profile-use).
Type * getType() const
All values are typed, get the type of this value.
static cl::opt< bool > DisableValueProfiling("disable-vp", cl::init(false), cl::Hidden, cl::desc("Disable Value Profiling"))
static NodeRef getEntryNode(const PGOUseFunc *G)
static bool isIndirectBrTarget(BasicBlock *BB)
static void createIRLevelProfileFlagVariable(Module &M)
void setComdat(Comdat *C)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
static void setBranchWeights(SwitchInst *SI, ArrayRef< uint32_t > Weights)
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
BasicBlock * SplitCriticalEdge(Instruction *TI, unsigned SuccNum, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions())
If this edge is a critical edge, insert a new node to split the critical edge.
void initializePGOInstrumentationGenLegacyPassPass(PassRegistry &)
static bool InstrumentAllFunctions(Module &M, function_ref< BranchProbabilityInfo *(Function &)> LookupBPI, function_ref< BlockFrequencyInfo *(Function &)> LookupBFI)
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
static bool canRenameComdat(Function &F, std::unordered_multimap< Comdat *, GlobalValue *> &ComdatMembers)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
static nodes_iterator nodes_end(const PGOUseFunc *G)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
amdgpu Simplify well known AMD library false Value * Callee
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
instrprof_error get() const
Legacy analysis pass which computes BranchProbabilityInfo.
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
Value * getOperand(unsigned i) const
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static ChildIteratorType child_end(const NodeRef N)
Interval::succ_iterator succ_end(Interval *I)
static cl::opt< unsigned > MaxNumMemOPAnnotations("memop-max-annotations", cl::init(4), cl::Hidden, cl::ZeroOrMore, cl::desc("Max number of preicise value annotations for a single memop" "intrinsic"))
std::string message() const override
Return the error message as a string.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Same, but only replaced by something equivalent.
initializer< Ty > init(const Ty &Val)
StringRef getName() const
A set of analyses that are preserved following a run of a transformation pass.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
Conditional or Unconditional Branch instruction.
void setIrrLoopHeaderMetadata(Module *M, Instruction *TI, uint64_t Count)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
static StringRef getPredicateName(Predicate P)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
Represent the analysis usage information of a pass.
static cl::opt< PGOViewCountsType > PGOViewRawCounts("pgo-view-raw-counts", cl::Hidden, cl::desc("A boolean option to show CFG dag or text " "with raw profile counts from " "profile data. See also option " "-pgo-view-counts. To limit graph " "display to only one function, use " "filtering option -view-bfi-func-name."), cl::values(clEnumValN(PGOVCT_None, "none", "do not show."), clEnumValN(PGOVCT_Graph, "graph", "show a graph."), clEnumValN(PGOVCT_Text, "text", "show in text.")))
static cl::opt< bool > 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"))
ModulePass * createPGOInstrumentationUseLegacyPass(StringRef Filename=StringRef(""))
This instruction compares its operands according to the predicate given to the constructor.
static std::string getBranchCondString(Instruction *TI)
Interval::pred_iterator pred_end(Interval *I)
static uint64_t calculateCountScale(uint64_t MaxCount)
Calculate what to divide by to scale counts.
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
static cl::opt< bool > NoPGOWarnMismatchComdat("no-pgo-warn-mismatch-comdat", cl::init(true), cl::Hidden, cl::desc("The option is used to turn on/off " "warnings about hash mismatch for comdat " "functions."))
void initializePGOInstrumentationUseLegacyPassPass(PassRegistry &)
DenseMap< const BasicBlock *, std::unique_ptr< BBInfo > > BBInfos
const Value * getCondition() const
static uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale)
Scale an individual branch count.
Comdat * getOrInsertComdat(StringRef Name)
Return the Comdat in the module with the specified name.
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...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Class to represent profile counts.
void createPGOFuncNameMetadata(Function &F, StringRef PGOFuncName)
Create the PGOFuncName meta data if PGOFuncName is different from function's raw name.
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
Triple - Helper class for working with autoconf configuration names.
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...
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
BBInfo * findBBInfo(const BasicBlock *BB) const
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
DOTGraphTraits(bool isSimple=false)
Analysis pass which computes BlockFrequencyInfo.
This is the common base class for memset/memcpy/memmove.
This is the shared class of boolean and integer constants.
void setSelectionKind(SelectionKind Val)
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
static nodes_iterator nodes_begin(const PGOUseFunc *G)
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 bool annotateAllFunctions(Module &M, StringRef ProfileFileName, StringRef ProfileRemappingFileName, function_ref< BranchProbabilityInfo *(Function &)> LookupBPI, function_ref< BlockFrequencyInfo *(Function &)> LookupBFI)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
pgo instr PGO instrumentation
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
uint64_t scale(uint64_t Num) const
Scale a large integer.
reference get()
Returns a reference to the stored T value.
bool isConditional() const
void dumpEdges(raw_ostream &OS, const Twine &Message) const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Class for arbitrary precision integers.
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."))
BBInfo & getBBInfo(const BasicBlock *BB) const
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
const Comdat * getComdat() const
pgo instr Read PGO instrumentation profile
Predicate getPredicate() const
Return the predicate for this instruction.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
std::vector< Instruction * > findIndirectCalls(Function &F)
Analysis providing branch probability information.
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...
Profiling information for a single function.
Expected< InstrProfRecord > getInstrProfRecord(StringRef FuncName, uint64_t FuncHash)
Return the NamedInstrProfRecord associated with FuncName and FuncHash.
void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
std::string getPGOFuncName(const Function &F, bool InLTO=false, uint64_t Version=INSTR_PROF_INDEX_VERSION)
Return the modified name for function F suitable to be used the key for profile lookup.
bool SplitIndirectBrCriticalEdges(Function &F, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr)
StringRef getName() const
Return a constant reference to the value's name.
const Function * getParent() const
Return the enclosing method, or null if none.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
GlobalVariable * createPGOFuncNameVar(Function &F, StringRef PGOFuncName)
Create and return the global variable for function name used in PGO instrumentation.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Keep one copy of named function when linking (weak)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value *> Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
static cl::opt< unsigned > MaxNumAnnotations("icp-max-annotations", cl::init(3), cl::Hidden, cl::ZeroOrMore, cl::desc("Max number of annotations for a single indirect " "call callsite"))
std::string str() const
Return the twine contents as a std::string.
cl::opt< PGOViewCountsType > PGOViewCounts
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
static void instrumentOneFunc(Function &F, Module *M, BranchProbabilityInfo *BPI, BlockFrequencyInfo *BFI, std::unordered_multimap< Comdat *, GlobalValue *> &ComdatMembers)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
LLVM Value Representation.
void update(ArrayRef< char > Data)
Lightweight error class with error context and mandatory checking.
BasicBlock::iterator GetInsertPoint() const
DefaultDOTGraphTraits - This class provides the default implementations of all of the DOTGraphTraits ...
cl::opt< std::string > ViewBlockFreqFuncName
StringRef - Represent a constant reference to a string, i.e.
Reader for the indexed binary instrprof format.
A container for analyses that lazily runs them and caches their results.
static void collectComdatMembers(Module &M, std::unordered_multimap< Comdat *, GlobalValue *> &ComdatMembers)
This header defines various interfaces for pass management in LLVM.
static std::string getSimpleNodeName(const BasicBlock *Node)
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 Expected< std::unique_ptr< IndexedInstrProfReader > > create(const Twine &Path, const Twine &RemappingPath="")
Factory method to create an indexed reader.
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...
const BasicBlock * getParent() const
SelectionKind getSelectionKind() const
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...