14#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYINFOIMPL_H
15#define LLVM_ANALYSIS_BLOCKFREQUENCYINFOIMPL_H
52#define DEBUG_TYPE "block-freq"
61class BranchProbabilityInfo;
65class MachineBasicBlock;
66class MachineBranchProbabilityInfo;
99 return BlockMass(std::numeric_limits<uint64_t>::max());
104 bool isFull()
const {
return Mass == std::numeric_limits<uint64_t>::max(); }
114 Mass = Sum < Mass ? std::numeric_limits<uint64_t>::max() : Sum;
124 Mass = Diff > Mass ? 0 : Diff;
129 Mass =
P.scale(Mass);
207 return std::numeric_limits<uint32_t>::max() - 1;
238 template <
class It1,
class It2>
243 Nodes.insert(
Nodes.end(), FirstOther, LastOther);
295 return Loop->Parent->Parent;
313 return L ? L->getHeader() :
Node;
320 while (L->Parent && L->Parent->IsPackaged)
335 return Loop->Parent->Mass;
465 std::list<LoopData>::iterator Insert);
523 std::optional<uint64_t>
525 bool AllowSynthetic =
false)
const;
526 std::optional<uint64_t>
528 bool AllowSynthetic =
false)
const;
539namespace bfi_detail {
559template <
class BlockT,
class BFIImplT>
570 assert(BB &&
"Unexpected nullptr");
571 auto MachineName =
"BB" +
Twine(BB->getNumber());
572 if (BB->getBasicBlock())
573 return (MachineName +
"[" + BB->getName() +
"]").str();
574 return MachineName.str();
578 assert(BB &&
"Unexpected nullptr");
609 using iterator = std::deque<const IrrNode *>::const_iterator;
630 template <
class BlockEdgesAdder>
632 BlockEdgesAdder addBlockEdges) :
BFI(
BFI) {
636 template <
class BlockEdgesAdder>
637 void initialize(
const BFIBase::LoopData *OuterLoop,
638 BlockEdgesAdder addBlockEdges);
648 template <
class BlockEdgesAdder>
650 BlockEdgesAdder addBlockEdges);
652 const BFIBase::LoopData *OuterLoop);
655template <
class BlockEdgesAdder>
657 BlockEdgesAdder addBlockEdges) {
660 for (
auto N : OuterLoop->
Nodes)
664 for (
uint32_t Index = 0; Index <
BFI.Working.size(); ++Index)
665 addEdges(Index, OuterLoop, addBlockEdges);
670template <
class BlockEdgesAdder>
673 BlockEdgesAdder addBlockEdges) {
678 const auto &Working =
BFI.Working[
Node.Index];
680 if (Working.isAPackage())
681 for (
const auto &
I : Working.Loop->Exits)
684 addBlockEdges(*
this, Irr, OuterLoop);
846 using BranchProbabilityInfoT =
852 using BFICallbackVH =
855 const BranchProbabilityInfoT *BPI =
nullptr;
856 const LoopInfoT *LI =
nullptr;
857 const FunctionT *F =
nullptr;
860 std::vector<BFICallbackVH> RPOT;
863 BlockNode getNode(
const BlockT *BB)
const {
return Nodes.lookup(BB); }
867 return RPOT[
Node.Index];
873 void initializeRPOT();
882 void initializeLoops();
910 bool tryToComputeMassInFunction();
924 void computeIrreducibleMass(
LoopData *OuterLoop,
925 std::list<LoopData>::iterator Insert);
936 void computeMassInLoops();
944 void computeMassInFunction();
946 std::string getBlockName(
const BlockNode &
Node)
const override {
960 bool needIterativeInference()
const;
963 void applyIterativeInference();
965 using ProbMatrixType = std::vector<std::vector<std::pair<size_t, Scaled64>>>;
968 void iterativeInference(
const ProbMatrixType &ProbMatrix,
969 std::vector<Scaled64> &Freq)
const;
973 void findReachableBlocks(std::vector<const BlockT *> &Blocks)
const;
977 void initTransitionProbabilities(
978 const std::vector<const BlockT *> &Blocks,
980 ProbMatrixType &ProbMatrix)
const;
985 Scaled64 discrepancy(
const ProbMatrixType &ProbMatrix,
986 const std::vector<Scaled64> &Freq)
const;
994 void calculate(
const FunctionT &F,
const BranchProbabilityInfoT &BPI,
995 const LoopInfoT &LI);
1003 std::optional<uint64_t>
1005 bool AllowSynthetic =
false)
const {
1010 std::optional<uint64_t>
1012 bool AllowSynthetic =
false)
const {
1027 auto It = Nodes.find(BB);
1028 assert(It != Nodes.end() &&
"cannot forget block that was never seen");
1029 RPOT[It->second.Index] = {};
1037 const BranchProbabilityInfoT &
getBPI()
const {
return *BPI; }
1059template <
class BFIImplT>
1083template <
class BFIImplT>
1098 const BranchProbabilityInfoT &BPI,
1099 const LoopInfoT &LI) {
1112 <<
"\n================="
1113 << std::string(F.getName().size(),
'=') <<
"\n");
1119 computeMassInLoops();
1120 computeMassInFunction();
1124 if (needIterativeInference())
1125 applyIterativeInference();
1132 for (
const BlockT &BB : F)
1133 if (!Nodes.count(&BB))
1141 auto [It, Inserted] = Nodes.try_emplace(BB);
1149 It->second = NewNode;
1150 Freqs.emplace_back();
1151 RPOT.emplace_back(BB,
this);
1156template <
class BT>
void BlockFrequencyInfoImpl<BT>::initializeRPOT() {
1157 const BlockT *Entry = &
F->front();
1158 RPOT.reserve(
F->size());
1160 RPOT.emplace_back(BB,
this);
1161 std::reverse(RPOT.begin(), RPOT.end());
1163 assert(RPOT.size() - 1 <= BlockNode::getMaxIndex() &&
1164 "More nodes in function than Block Frequency Info supports");
1168 BlockNode
Node = BlockNode(Idx);
1173 Working.reserve(RPOT.size());
1174 for (
size_t Index = 0; Index < RPOT.size(); ++Index)
1175 Working.emplace_back(Index);
1176 Freqs.resize(RPOT.size());
1179template <
class BT>
void BlockFrequencyInfoImpl<BT>::initializeLoops() {
1185 std::deque<std::pair<const LoopT *, LoopData *>> Q;
1186 for (
const LoopT *L : *LI)
1187 Q.emplace_back(L,
nullptr);
1188 while (!Q.empty()) {
1189 const LoopT *
Loop = Q.front().first;
1190 LoopData *Parent = Q.front().second;
1194 assert(Header.isValid());
1196 Loops.emplace_back(Parent, Header);
1197 Working[Header.Index].Loop = &
Loops.back();
1200 for (
const LoopT *L : *
Loop)
1201 Q.emplace_back(L, &
Loops.back());
1206 for (
size_t Index = 0;
Index < RPOT.size(); ++
Index) {
1208 if (Working[Index].isLoopHeader()) {
1209 LoopData *ContainingLoop = Working[
Index].getContainingLoop();
1211 ContainingLoop->Nodes.push_back(Index);
1215 const LoopT *
Loop = LI->getLoopFor(RPOT[Index]);
1221 assert(Header.isValid());
1222 const auto &HeaderData = Working[Header.Index];
1223 assert(HeaderData.isLoopHeader());
1225 Working[
Index].Loop = HeaderData.Loop;
1226 HeaderData.Loop->Nodes.push_back(Index);
1232template <
class BT>
void BlockFrequencyInfoImpl<BT>::computeMassInLoops() {
1234 for (
auto L =
Loops.rbegin(),
E =
Loops.rend(); L !=
E; ++L) {
1235 if (computeMassInLoop(*L))
1237 auto Next = std::next(L);
1238 computeIrreducibleMass(&*L,
L.base());
1239 L = std::prev(
Next);
1240 if (computeMassInLoop(*L))
1247bool BlockFrequencyInfoImpl<BT>::computeMassInLoop(LoopData &
Loop) {
1251 if (
Loop.isIrreducible()) {
1254 unsigned NumHeadersWithWeight = 0;
1255 std::optional<uint64_t> MinHeaderWeight;
1258 for (uint32_t
H = 0;
H <
Loop.NumHeaders; ++
H) {
1259 auto &HeaderNode =
Loop.Nodes[
H];
1260 const BlockT *
Block = getBlock(HeaderNode);
1261 IsIrrLoopHeader.set(
Loop.Nodes[
H].Index);
1262 std::optional<uint64_t> HeaderWeight =
Block->getIrrLoopHeaderWeight();
1263 if (!HeaderWeight) {
1266 HeadersWithoutWeight.insert(
H);
1270 <<
" has irr loop header weight " << *HeaderWeight
1272 NumHeadersWithWeight++;
1273 uint64_t HeaderWeightValue = *HeaderWeight;
1274 if (!MinHeaderWeight || HeaderWeightValue < MinHeaderWeight)
1275 MinHeaderWeight = HeaderWeightValue;
1276 if (HeaderWeightValue) {
1277 Dist.addLocal(HeaderNode, HeaderWeightValue);
1286 if (!MinHeaderWeight)
1287 MinHeaderWeight = 1;
1288 for (uint32_t
H : HeadersWithoutWeight) {
1289 auto &HeaderNode =
Loop.Nodes[
H];
1290 assert(!getBlock(HeaderNode)->getIrrLoopHeaderWeight() &&
1291 "Shouldn't have a weight metadata");
1292 uint64_t MinWeight = *MinHeaderWeight;
1296 Dist.addLocal(HeaderNode, MinWeight);
1298 distributeIrrLoopHeaderMass(Dist);
1299 for (
const BlockNode &M :
Loop.Nodes)
1300 if (!propagateMassToSuccessors(&
Loop, M))
1302 if (NumHeadersWithWeight == 0)
1304 adjustLoopHeaderMass(
Loop);
1306 Working[
Loop.
getHeader().Index].getMass() = BlockMass::getFull();
1309 for (
const BlockNode &M :
Loop.members())
1310 if (!propagateMassToSuccessors(&
Loop, M))
1315 computeLoopScale(
Loop);
1321bool BlockFrequencyInfoImpl<BT>::tryToComputeMassInFunction() {
1324 assert(!Working.empty() &&
"no blocks in function");
1325 assert(!Working[0].isLoopHeader() &&
"entry block is a loop header");
1327 Working[0].getMass() = BlockMass::getFull();
1328 for (
size_t i = 0, n = RPOT.size(); i != n; ++i) {
1330 if (Working[i].isPackaged())
1333 if (!propagateMassToSuccessors(
nullptr, BlockNode(i)))
1339template <
class BT>
void BlockFrequencyInfoImpl<BT>::computeMassInFunction() {
1340 if (tryToComputeMassInFunction())
1342 computeIrreducibleMass(
nullptr,
Loops.begin());
1343 if (tryToComputeMassInFunction())
1349bool BlockFrequencyInfoImpl<BT>::needIterativeInference()
const {
1352 if (!
F->getFunction().hasProfileData())
1356 for (
auto L =
Loops.rbegin(),
E =
Loops.rend(); L !=
E; ++L) {
1357 if (
L->isIrreducible())
1363template <
class BT>
void BlockFrequencyInfoImpl<BT>::applyIterativeInference() {
1368 std::vector<const BlockT *> ReachableBlocks;
1369 findReachableBlocks(ReachableBlocks);
1370 if (ReachableBlocks.empty())
1377 auto Freq = std::vector<Scaled64>(ReachableBlocks.size());
1379 for (
size_t I = 0;
I < ReachableBlocks.size();
I++) {
1380 const BlockT *BB = ReachableBlocks[
I];
1382 Freq[
I] = getFloatingBlockFreq(BB);
1385 assert(!SumFreq.isZero() &&
"empty initial block frequencies");
1387 LLVM_DEBUG(
dbgs() <<
"Applying iterative inference for " <<
F->getName()
1388 <<
" with " << ReachableBlocks.size() <<
" blocks\n");
1391 for (
auto &
Value : Freq) {
1397 ProbMatrixType ProbMatrix;
1398 initTransitionProbabilities(ReachableBlocks, BlockIndex, ProbMatrix);
1401 iterativeInference(ProbMatrix, Freq);
1404 for (
const BlockT &BB : *
F) {
1406 if (!
Node.isValid())
1408 if (
auto It = BlockIndex.find(&BB); It != BlockIndex.end())
1409 Freqs[
Node.Index].Scaled = Freq[It->second];
1411 Freqs[
Node.Index].Scaled = Scaled64::getZero();
1416void BlockFrequencyInfoImpl<BT>::iterativeInference(
1417 const ProbMatrixType &ProbMatrix, std::vector<Scaled64> &Freq)
const {
1419 "incorrectly specified precision");
1421 const auto Precision =
1427 << discrepancy(ProbMatrix, Freq).
toString() <<
"\n");
1431 auto Successors = std::vector<std::vector<size_t>>(Freq.size());
1432 for (
size_t I = 0;
I < Freq.size();
I++) {
1433 for (
const auto &Jump : ProbMatrix[
I]) {
1434 Successors[Jump.first].push_back(
I);
1442 auto IsActive =
BitVector(Freq.size(),
false);
1443 std::queue<size_t> ActiveSet;
1444 for (
size_t I = 0;
I < Freq.size();
I++) {
1453 while (It++ < MaxIterations && !ActiveSet.empty()) {
1454 size_t I = ActiveSet.front();
1456 IsActive[
I] =
false;
1462 Scaled64 OneMinusSelfProb = Scaled64::getOne();
1463 for (
const auto &Jump : ProbMatrix[
I]) {
1464 if (Jump.first ==
I) {
1465 OneMinusSelfProb -= Jump.second;
1467 NewFreq += Freq[Jump.first] * Jump.second;
1470 if (OneMinusSelfProb != Scaled64::getOne())
1471 NewFreq /= OneMinusSelfProb;
1475 auto Change = Freq[
I] >= NewFreq ? Freq[
I] - NewFreq : NewFreq - Freq[
I];
1476 if (Change > Precision) {
1479 for (
size_t Succ : Successors[
I]) {
1480 if (!IsActive[Succ]) {
1481 ActiveSet.push(Succ);
1482 IsActive[Succ] =
true;
1491 LLVM_DEBUG(
dbgs() <<
" Completed " << It <<
" inference iterations"
1492 <<
format(
" (%0.0f per block)",
double(It) / Freq.size())
1496 << discrepancy(ProbMatrix, Freq).
toString() <<
"\n");
1501void BlockFrequencyInfoImpl<BT>::findReachableBlocks(
1502 std::vector<const BlockT *> &Blocks)
const {
1505 std::queue<const BlockT *>
Queue;
1507 const BlockT *
Entry = &
F->front();
1509 Reachable.insert(Entry);
1510 while (!
Queue.empty()) {
1511 const BlockT *SrcBB =
Queue.front();
1514 auto EP = BPI->getEdgeProbability(SrcBB, DstBB);
1517 if (Reachable.insert(DstBB).second)
1525 for (
const BlockT &BB : *
F) {
1528 if (!HasSucc && Reachable.count(&BB)) {
1530 InverseReachable.insert(&BB);
1533 while (!
Queue.empty()) {
1534 const BlockT *SrcBB =
Queue.front();
1537 auto EP = BPI->getEdgeProbability(DstBB, SrcBB);
1540 if (InverseReachable.insert(DstBB).second)
1546 Blocks.reserve(
F->size());
1547 for (
const BlockT &BB : *
F) {
1548 if (Reachable.count(&BB) && InverseReachable.count(&BB)) {
1549 Blocks.push_back(&BB);
1555void BlockFrequencyInfoImpl<BT>::initTransitionProbabilities(
1556 const std::vector<const BlockT *> &Blocks,
1558 ProbMatrixType &ProbMatrix)
const {
1559 const size_t NumBlocks = Blocks.size();
1560 auto Succs = std::vector<std::vector<std::pair<size_t, Scaled64>>>(NumBlocks);
1561 auto SumProb = std::vector<Scaled64>(NumBlocks);
1564 for (
size_t Src = 0; Src < NumBlocks; Src++) {
1565 const BlockT *BB = Blocks[Src];
1569 auto BlockIndexIt = BlockIndex.find(
SI);
1570 if (BlockIndexIt == BlockIndex.end())
1573 if (!UniqueSuccs.insert(
SI).second)
1576 auto EP = BPI->getEdgeProbability(BB,
SI);
1581 Scaled64::getFraction(EP.getNumerator(), EP.getDenominator());
1582 size_t Dst = BlockIndexIt->second;
1583 Succs[Src].push_back(std::make_pair(Dst, EdgeProb));
1584 SumProb[Src] += EdgeProb;
1589 ProbMatrix = ProbMatrixType(NumBlocks);
1590 for (
size_t Src = 0; Src < NumBlocks; Src++) {
1592 if (Succs[Src].
empty())
1595 assert(!SumProb[Src].
isZero() &&
"Zero sum probability of non-exit block");
1596 for (
auto &Jump : Succs[Src]) {
1597 size_t Dst = Jump.first;
1598 Scaled64 Prob = Jump.second;
1599 ProbMatrix[Dst].push_back(std::make_pair(Src, Prob / SumProb[Src]));
1604 size_t EntryIdx = BlockIndex.find(&
F->front())->second;
1605 for (
size_t Src = 0; Src < NumBlocks; Src++) {
1606 if (Succs[Src].
empty()) {
1607 ProbMatrix[EntryIdx].push_back(std::make_pair(Src, Scaled64::getOne()));
1615 const ProbMatrixType &ProbMatrix,
const std::vector<Scaled64> &Freq)
const {
1616 assert(Freq[0] > 0 &&
"Incorrectly computed frequency of the entry block");
1617 Scaled64 Discrepancy;
1618 for (
size_t I = 0;
I < ProbMatrix.size();
I++) {
1620 for (
const auto &Jump : ProbMatrix[
I]) {
1621 Sum += Freq[Jump.first] * Jump.second;
1623 Discrepancy += Freq[
I] >= Sum ? Freq[
I] - Sum : Sum - Freq[
I];
1626 return Discrepancy / Freq[0];
1631void BlockFrequencyInfoImpl<BT>::computeIrreducibleMass(
1632 LoopData *OuterLoop, std::list<LoopData>::iterator Insert) {
1634 if (OuterLoop)
dbgs()
1635 <<
"loop: " << getLoopName(*OuterLoop) <<
"\n";
1636 else dbgs() <<
"function\n");
1640 auto addBlockEdges = [&](IrreducibleGraph &
G, IrreducibleGraph::IrrNode &Irr,
1641 const LoopData *OuterLoop) {
1642 const BlockT *BB = RPOT[Irr.Node.Index];
1644 G.addEdge(Irr,
getNode(Succ), OuterLoop);
1646 IrreducibleGraph
G(*
this, OuterLoop, addBlockEdges);
1648 for (
auto &L : analyzeIrreducible(
G, OuterLoop, Insert))
1649 computeMassInLoop(L);
1653 updateLoopWithIrreducible(*OuterLoop);
1663BlockFrequencyInfoImpl<BT>::propagateMassToSuccessors(LoopData *OuterLoop,
1664 const BlockNode &
Node) {
1668 if (
auto *Loop = Working[
Node.Index].getPackagedLoop()) {
1669 assert(Loop != OuterLoop &&
"Cannot propagate mass in a packaged loop");
1670 if (!addLoopSuccessorsToDist(OuterLoop, *Loop, Dist))
1674 const BlockT *BB = getBlock(Node);
1687 distributeMass(Node, OuterLoop, Dist);
1695 OS <<
"block-frequency-info: " << F->getName() <<
"\n";
1696 for (
const BlockT &BB : *F) {
1702 F->getFunction(), getNode(&BB)))
1704 if (std::optional<uint64_t> IrrLoopHeaderWeight =
1705 BB.getIrrLoopHeaderWeight())
1706 OS <<
", irr_loop_header_weight = " << *IrrLoopHeaderWeight;
1721 for (
auto &Entry : Nodes) {
1722 const BlockT *BB = Entry.first;
1724 ValidNodes[BB] = Entry.second;
1727 for (
auto &Entry :
Other.Nodes) {
1728 const BlockT *BB = Entry.first;
1730 OtherValidNodes[BB] = Entry.second;
1733 unsigned NumValidNodes = ValidNodes.
size();
1734 unsigned NumOtherValidNodes = OtherValidNodes.
size();
1735 if (NumValidNodes != NumOtherValidNodes) {
1737 dbgs() <<
"Number of blocks mismatch: " << NumValidNodes <<
" vs "
1738 << NumOtherValidNodes <<
"\n";
1740 for (
auto &Entry : ValidNodes) {
1741 const BlockT *BB = Entry.first;
1743 if (
auto It = OtherValidNodes.
find(BB); It != OtherValidNodes.
end()) {
1746 const auto &OtherFreq =
Other.Freqs[OtherNode.
Index];
1747 if (Freq.Integer != OtherFreq.Integer) {
1750 << Freq.Integer <<
" vs " << OtherFreq.Integer <<
"\n";
1755 <<
Node.Index <<
" does not exist in Other.\n";
1764 dbgs() <<
"Other\n";
1767 assert(Match &&
"BFI mismatch");
1775template <
class BlockFrequencyInfoT,
class BranchProbabilityInfoT>
1788 return G->getFunction()->getName();
1792 unsigned HotPercentThreshold = 0) {
1794 if (!HotPercentThreshold)
1804 std::max(
MaxFrequency, Graph->getBlockFreq(
N).getFrequency());
1820 GVDAGType GType,
int layout_order = -1) {
1824 if (layout_order != -1)
1825 OS <<
Node->getName() <<
"[" << layout_order <<
"] : ";
1827 OS <<
Node->getName() <<
" : ";
1833 OS << Graph->getBlockFreq(
Node).getFrequency();
1836 auto Count = Graph->getBlockProfileCount(
Node);
1845 "never reach this point.");
1851 const BlockFrequencyInfoT *BFI,
1852 const BranchProbabilityInfoT *BPI,
1853 unsigned HotPercentThreshold = 0) {
1865 if (HotPercentThreshold) {
1870 if (EFreq >= HotFreq)
1871 OS <<
",color=\"red\"";
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
This file implements the BitVector class.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Branch Probability Basic Block static false std::string getBlockName(const MachineBasicBlock *BB)
Helper to print the name of a MBB.
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the SparseBitVector class.
Value handle that asserts if the Value is deleted.
LLVM Basic Block Representation.
Base class for BlockFrequencyInfoImpl.
std::vector< WorkingData > Working
Loop data: see initializeLoops().
virtual ~BlockFrequencyInfoImplBase()=default
Virtual destructor.
std::list< LoopData > Loops
Indexed information about loops.
bool addLoopSuccessorsToDist(const LoopData *OuterLoop, LoopData &Loop, Distribution &Dist)
Add all edges out of a packaged loop to the distribution.
ScaledNumber< uint64_t > Scaled64
std::string getLoopName(const LoopData &Loop) const
bool isIrrLoopHeader(const BlockNode &Node)
void computeLoopScale(LoopData &Loop)
Compute the loop scale for a loop.
bfi_detail::BlockMass BlockMass
void packageLoop(LoopData &Loop)
Package up a loop.
virtual raw_ostream & print(raw_ostream &OS) const
virtual std::string getBlockName(const BlockNode &Node) const
void finalizeMetrics()
Finalize frequency metrics.
void setBlockFreq(const BlockNode &Node, BlockFrequency Freq)
BlockFrequency getEntryFreq() const
void updateLoopWithIrreducible(LoopData &OuterLoop)
Update a loop after packaging irreducible SCCs inside of it.
void clear()
Clear all memory.
std::optional< uint64_t > getBlockProfileCount(const Function &F, const BlockNode &Node, bool AllowSynthetic=false) const
BlockFrequency getBlockFreq(const BlockNode &Node) const
void distributeIrrLoopHeaderMass(Distribution &Dist)
iterator_range< std::list< LoopData >::iterator > analyzeIrreducible(const bfi_detail::IrreducibleGraph &G, LoopData *OuterLoop, std::list< LoopData >::iterator Insert)
Analyze irreducible SCCs.
bool addToDist(Distribution &Dist, const LoopData *OuterLoop, const BlockNode &Pred, const BlockNode &Succ, uint64_t Weight)
Add an edge to the distribution.
void unwrapLoops()
Unwrap loops.
std::optional< uint64_t > getProfileCountFromFreq(const Function &F, BlockFrequency Freq, bool AllowSynthetic=false) const
Scaled64 getFloatingBlockFreq(const BlockNode &Node) const
void distributeMass(const BlockNode &Source, LoopData *OuterLoop, Distribution &Dist)
Distribute mass according to a distribution.
SparseBitVector IsIrrLoopHeader
Whether each block is an irreducible loop header.
std::vector< FrequencyData > Freqs
Data about each block. This is used downstream.
void adjustLoopHeaderMass(LoopData &Loop)
Adjust the mass of all headers in an irreducible loop.
bool isIrrLoopHeader(const BlockT *BB)
std::optional< uint64_t > getBlockProfileCount(const Function &F, const BlockT *BB, bool AllowSynthetic=false) const
const BranchProbabilityInfoT & getBPI() const
const FunctionT * getFunction() const
void verifyMatch(BlockFrequencyInfoImpl< BT > &Other) const
Scaled64 getFloatingBlockFreq(const BlockT *BB) const
std::optional< uint64_t > getProfileCountFromFreq(const Function &F, BlockFrequency Freq, bool AllowSynthetic=false) const
void calculate(const FunctionT &F, const BranchProbabilityInfoT &BPI, const LoopInfoT &LI)
void setBlockFreq(const BlockT *BB, BlockFrequency Freq)
BlockFrequencyInfoImpl()=default
raw_ostream & print(raw_ostream &OS) const override
Print the frequencies for the current function.
void forgetBlock(const BlockT *BB)
BlockFrequency getBlockFreq(const BlockT *BB) const
Analysis providing branch probability information.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
static uint32_t getDenominator()
uint32_t getNumerator() const
CallbackVH(const CallbackVH &)=default
iterator find(const_arg_type_t< KeyT > Val)
Implements a dense probed hash-table based set.
BlockT * getHeader() const
Represents a single loop in the control flow graph.
Simple representation of a scaled number.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
ptrdiff_t difference_type
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.
std::string str() const
str - Get the contents as an std::string.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
Value * getValPtr() const
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
void deleted() override
Callback for Value destruction.
BFICallbackVH(const BasicBlock *BB, BFIImplT *BFIImpl)
virtual ~BFICallbackVH()=default
BFICallbackVH(const MachineBasicBlock *MBB, BFIImplT *)
bool operator<(BlockMass X) const
bool operator>(BlockMass X) const
raw_ostream & print(raw_ostream &OS) const
bool operator==(BlockMass X) const
static BlockMass getEmpty()
BlockMass & operator-=(BlockMass X)
Subtract another mass.
bool operator<=(BlockMass X) const
BlockMass & operator*=(BranchProbability P)
static BlockMass getFull()
bool operator!=(BlockMass X) const
BlockMass & operator+=(BlockMass X)
Add another mass.
bool operator>=(BlockMass X) const
ScaledNumber< uint64_t > toScaled() const
Convert to scaled number.
void reserve(size_t Size)
Grow the DenseSet so that it can contain at least NumEntries items before resizing again.
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::string getBlockName(const BlockT *BB)
Get the name of a MachineBasicBlock.
BlockMass operator*(BlockMass L, BranchProbability R)
BlockMass operator+(BlockMass L, BlockMass R)
raw_ostream & operator<<(raw_ostream &OS, BlockMass X)
BlockMass operator-(BlockMass L, BlockMass R)
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
uint32_t getWeightFromBranchProb(const BranchProbability Prob)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< po_iterator< T > > post_order(const T &G)
llvm::cl::opt< unsigned > IterativeBFIMaxIterationsPerBlock
llvm::cl::opt< bool > UseIterativeBFIInference
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
Function::ProfileCount ProfileCount
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
llvm::cl::opt< bool > CheckBFIUnknownBlockQueries
iterator_range< typename GraphTraits< Inverse< GraphType > >::ChildIteratorType > inverse_children(const typename GraphTraits< GraphType >::NodeRef &G)
FunctionAddr VTableAddr Next
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
LLVM_ABI Printable printBlockFreq(const BlockFrequencyInfo &BFI, BlockFrequency Freq)
Print the block frequency Freq relative to the current functions entry frequency.
llvm::cl::opt< double > IterativeBFIPrecision
Implement std::hash so that hash_code can be used in STL containers.
GraphTraits< BlockFrequencyInfoT * > GTraits
std::string getNodeAttributes(NodeRef Node, const BlockFrequencyInfoT *Graph, unsigned HotPercentThreshold=0)
typename GTraits::nodes_iterator NodeIter
typename GTraits::NodeRef NodeRef
typename GTraits::ChildIteratorType EdgeIter
std::string getNodeLabel(NodeRef Node, const BlockFrequencyInfoT *Graph, GVDAGType GType, int layout_order=-1)
std::string getEdgeAttributes(NodeRef Node, EdgeIter EI, const BlockFrequencyInfoT *BFI, const BranchProbabilityInfoT *BPI, unsigned HotPercentThreshold=0)
BFIDOTGraphTraitsBase(bool isSimple=false)
static StringRef getGraphName(const BlockFrequencyInfoT *G)
Representative of a block.
bool operator==(const BlockNode &X) const
bool operator!=(const BlockNode &X) const
bool operator<(const BlockNode &X) const
bool operator>=(const BlockNode &X) const
BlockNode(IndexType Index)
static size_t getMaxIndex()
bool operator<=(const BlockNode &X) const
bool operator>(const BlockNode &X) const
Distribution of unscaled probability weight.
void addBackedge(const BlockNode &Node, uint64_t Amount)
SmallVector< Weight, 4 > WeightList
WeightList Weights
Individual successor weights.
uint64_t Total
Sum of all weights.
void normalize()
Normalize the distribution.
void addExit(const BlockNode &Node, uint64_t Amount)
bool DidOverflow
Whether Total did overflow.
void addLocal(const BlockNode &Node, uint64_t Amount)
Stats about a block itself.
bool isHeader(const BlockNode &Node) const
SmallVector< std::pair< BlockNode, BlockMass >, 4 > ExitMap
LoopData * Parent
The parent loop.
LoopData(LoopData *Parent, It1 FirstHeader, It1 LastHeader, It2 FirstOther, It2 LastOther)
ExitMap Exits
Successor edges (and weights).
uint32_t NumHeaders
Number of headers.
bool IsPackaged
Whether this has been packaged.
LoopData(LoopData *Parent, const BlockNode &Header)
SmallVector< BlockNode, 4 > NodeList
NodeList::const_iterator members_end() const
NodeList::const_iterator members_begin() const
bool isIrreducible() const
BlockNode getHeader() const
SmallVector< BlockMass, 1 > HeaderMassList
NodeList Nodes
Header and the members of the loop.
HeaderMassList BackedgeMass
Mass returned to each loop header.
HeaderMassList::difference_type getHeaderIndex(const BlockNode &B)
iterator_range< NodeList::const_iterator > members() const
Unscaled probability weight.
Weight(DistType Type, BlockNode TargetNode, uint64_t Amount)
bool isPackaged() const
Has ContainingLoop been packaged up?
BlockMass Mass
Mass distribution from the entry block.
BlockMass & getMass()
Get the appropriate mass for a node.
WorkingData(const BlockNode &Node)
bool isAPackage() const
Has Loop been packaged up?
bool isLoopHeader() const
bool isDoubleLoopHeader() const
LoopData * Loop
The loop this block is inside.
LoopData * getContainingLoop() const
LoopData * getPackagedLoop() const
BlockNode getResolvedNode() const
Resolve a node to its representative.
bool isADoublePackage() const
Has Loop been packaged up twice?
DefaultDOTGraphTraits(bool simple=false)
static nodes_iterator nodes_end(const BlockFrequencyInfo *G)
static nodes_iterator nodes_begin(const BlockFrequencyInfo *G)
typename BlockFrequencyInfoT *::UnknownGraphTypeError NodeRef
iterator pred_end() const
IrrNode(const BlockNode &Node)
iterator pred_begin() const
iterator succ_begin() const
std::deque< const IrrNode * >::const_iterator iterator
std::deque< const IrrNode * > Edges
iterator succ_end() const
Graph of irreducible control flow.
void addNodesInFunction()
IrreducibleGraph(BFIBase &BFI, const BFIBase::LoopData *OuterLoop, BlockEdgesAdder addBlockEdges)
Construct an explicit graph containing irreducible control flow.
void addEdge(IrrNode &Irr, const BlockNode &Succ, const BFIBase::LoopData *OuterLoop)
BlockFrequencyInfoImplBase BFIBase
void addEdges(const BlockNode &Node, const BFIBase::LoopData *OuterLoop, BlockEdgesAdder addBlockEdges)
BFIBase::BlockNode BlockNode
std::vector< IrrNode > Nodes
SmallDenseMap< uint32_t, IrrNode *, 4 > Lookup
void initialize(const BFIBase::LoopData *OuterLoop, BlockEdgesAdder addBlockEdges)
void addNode(const BlockNode &Node)
void addNodesInLoop(const BFIBase::LoopData &OuterLoop)
BranchProbabilityInfo BranchProbabilityInfoT
AssertingVH< const BasicBlock > BlockKeyT
MachineLoopInfo LoopInfoT
MachineFunction FunctionT
MachineBranchProbabilityInfo BranchProbabilityInfoT
const MachineBasicBlock * BlockKeyT