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>
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)
670template <
class BlockEdgesAdder>
673 BlockEdgesAdder addBlockEdges) {
680 if (Working.isAPackage())
681 for (
const auto &
I : Working.Loop->Exits)
684 addBlockEdges(*
this, Irr, OuterLoop);
846 using BranchProbabilityInfoT =
855 const BranchProbabilityInfoT *BPI =
nullptr;
856 const LoopInfoT *LI =
nullptr;
857 const FunctionT *F =
nullptr;
860 std::vector<const BlockT *> RPOT;
863 using rpot_iterator =
typename std::vector<const BlockT *>::const_iterator;
865 rpot_iterator rpot_begin()
const {
return RPOT.
begin(); }
866 rpot_iterator rpot_end()
const {
return RPOT.end(); }
868 size_t getIndex(
const rpot_iterator &
I)
const {
return I - rpot_begin(); }
870 BlockNode getNode(
const rpot_iterator &
I)
const {
874 BlockNode getNode(
const BlockT *BB)
const {
return Nodes.
lookup(BB).first; }
878 return RPOT[
Node.Index];
884 void initializeRPOT();
893 void initializeLoops();
921 bool tryToComputeMassInFunction();
935 void computeIrreducibleMass(
LoopData *OuterLoop,
936 std::list<LoopData>::iterator Insert);
947 void computeMassInLoops();
955 void computeMassInFunction();
957 std::string getBlockName(
const BlockNode &
Node)
const override {
971 bool needIterativeInference()
const;
974 void applyIterativeInference();
976 using ProbMatrixType = std::vector<std::vector<std::pair<size_t, Scaled64>>>;
979 void iterativeInference(
const ProbMatrixType &ProbMatrix,
980 std::vector<Scaled64> &Freq)
const;
984 void findReachableBlocks(std::vector<const BlockT *> &
Blocks)
const;
988 void initTransitionProbabilities(
989 const std::vector<const BlockT *> &
Blocks,
991 ProbMatrixType &ProbMatrix)
const;
996 Scaled64 discrepancy(
const ProbMatrixType &ProbMatrix,
997 const std::vector<Scaled64> &Freq)
const;
1005 void calculate(
const FunctionT &F,
const BranchProbabilityInfoT &BPI,
1006 const LoopInfoT &LI);
1014 std::optional<uint64_t>
1016 bool AllowSynthetic =
false)
const {
1021 std::optional<uint64_t>
1023 bool AllowSynthetic =
false)
const {
1045 const BranchProbabilityInfoT &
getBPI()
const {
return *BPI; }
1065namespace bfi_detail {
1067template <
class BFIImplT>
1080 BFIImpl->forgetBlock(cast<BasicBlock>(getValPtr()));
1086template <
class BFIImplT>
1097 const BranchProbabilityInfoT &BPI,
1098 const LoopInfoT &LI) {
1111 <<
"\n================="
1112 << std::string(
F.getName().size(),
'=') <<
"\n");
1118 computeMassInLoops();
1119 computeMassInFunction();
1123 if (needIterativeInference())
1124 applyIterativeInference();
1131 for (
const BlockT &BB :
F)
1132 if (!Nodes.count(&BB))
1140 auto [It, Inserted] = Nodes.try_emplace(BB);
1149 Freqs.emplace_back();
1155 const BlockT *Entry = &
F->front();
1156 RPOT.reserve(
F->size());
1157 std::copy(
po_begin(Entry),
po_end(Entry), std::back_inserter(RPOT));
1158 std::reverse(RPOT.begin(), RPOT.end());
1160 assert(RPOT.size() - 1 <= BlockNode::getMaxIndex() &&
1161 "More nodes in function than Block Frequency Info supports");
1164 for (rpot_iterator
I = rpot_begin(),
E = rpot_end();
I !=
E; ++
I) {
1168 Nodes[*
I] = {
Node, BFICallbackVH(*
I,
this)};
1171 Working.reserve(RPOT.size());
1173 Working.emplace_back(
Index);
1174 Freqs.resize(RPOT.size());
1177template <
class BT>
void BlockFrequencyInfoImpl<BT>::initializeLoops() {
1183 std::deque<std::pair<const LoopT *, LoopData *>> Q;
1184 for (
const LoopT *L : *LI)
1185 Q.emplace_back(L,
nullptr);
1186 while (!Q.empty()) {
1187 const LoopT *Loop = Q.front().first;
1188 LoopData *Parent = Q.front().second;
1191 BlockNode Header =
getNode(Loop->getHeader());
1192 assert(Header.isValid());
1194 Loops.emplace_back(Parent, Header);
1195 Working[Header.Index].Loop = &
Loops.back();
1198 for (
const LoopT *L : *Loop)
1199 Q.emplace_back(L, &
Loops.back());
1206 if (Working[
Index].isLoopHeader()) {
1207 LoopData *ContainingLoop = Working[
Index].getContainingLoop();
1209 ContainingLoop->Nodes.push_back(
Index);
1213 const LoopT *Loop = LI->getLoopFor(RPOT[
Index]);
1218 BlockNode Header =
getNode(Loop->getHeader());
1219 assert(Header.isValid());
1220 const auto &HeaderData = Working[Header.Index];
1221 assert(HeaderData.isLoopHeader());
1223 Working[
Index].Loop = HeaderData.Loop;
1224 HeaderData.Loop->Nodes.push_back(
Index);
1230template <
class BT>
void BlockFrequencyInfoImpl<BT>::computeMassInLoops() {
1232 for (
auto L =
Loops.rbegin(),
E =
Loops.rend(); L !=
E; ++L) {
1233 if (computeMassInLoop(*L))
1235 auto Next = std::next(L);
1236 computeIrreducibleMass(&*L,
L.base());
1237 L = std::prev(Next);
1238 if (computeMassInLoop(*L))
1245bool BlockFrequencyInfoImpl<BT>::computeMassInLoop(LoopData &Loop) {
1247 LLVM_DEBUG(
dbgs() <<
"compute-mass-in-loop: " << getLoopName(Loop) <<
"\n");
1249 if (Loop.isIrreducible()) {
1252 unsigned NumHeadersWithWeight = 0;
1253 std::optional<uint64_t> MinHeaderWeight;
1254 DenseSet<uint32_t> HeadersWithoutWeight;
1255 HeadersWithoutWeight.reserve(Loop.NumHeaders);
1257 auto &HeaderNode = Loop.Nodes[
H];
1258 const BlockT *
Block = getBlock(HeaderNode);
1259 IsIrrLoopHeader.set(Loop.Nodes[
H].Index);
1260 std::optional<uint64_t> HeaderWeight =
Block->getIrrLoopHeaderWeight();
1261 if (!HeaderWeight) {
1264 HeadersWithoutWeight.insert(
H);
1268 <<
" has irr loop header weight " << *HeaderWeight
1270 NumHeadersWithWeight++;
1271 uint64_t HeaderWeightValue = *HeaderWeight;
1272 if (!MinHeaderWeight || HeaderWeightValue < MinHeaderWeight)
1273 MinHeaderWeight = HeaderWeightValue;
1274 if (HeaderWeightValue) {
1275 Dist.addLocal(HeaderNode, HeaderWeightValue);
1284 if (!MinHeaderWeight)
1285 MinHeaderWeight = 1;
1286 for (
uint32_t H : HeadersWithoutWeight) {
1287 auto &HeaderNode = Loop.Nodes[
H];
1288 assert(!getBlock(HeaderNode)->getIrrLoopHeaderWeight() &&
1289 "Shouldn't have a weight metadata");
1290 uint64_t MinWeight = *MinHeaderWeight;
1294 Dist.addLocal(HeaderNode, MinWeight);
1296 distributeIrrLoopHeaderMass(Dist);
1297 for (
const BlockNode &M : Loop.Nodes)
1298 if (!propagateMassToSuccessors(&Loop, M))
1300 if (NumHeadersWithWeight == 0)
1302 adjustLoopHeaderMass(Loop);
1304 Working[Loop.getHeader().Index].getMass() = BlockMass::getFull();
1305 if (!propagateMassToSuccessors(&Loop, Loop.getHeader()))
1307 for (
const BlockNode &M : Loop.members())
1308 if (!propagateMassToSuccessors(&Loop, M))
1313 computeLoopScale(Loop);
1319bool BlockFrequencyInfoImpl<BT>::tryToComputeMassInFunction() {
1322 assert(!Working.empty() &&
"no blocks in function");
1323 assert(!Working[0].isLoopHeader() &&
"entry block is a loop header");
1325 Working[0].getMass() = BlockMass::getFull();
1326 for (rpot_iterator
I = rpot_begin(), IE = rpot_end();
I !=
IE; ++
I) {
1329 if (Working[
Node.Index].isPackaged())
1332 if (!propagateMassToSuccessors(
nullptr,
Node))
1338template <
class BT>
void BlockFrequencyInfoImpl<BT>::computeMassInFunction() {
1339 if (tryToComputeMassInFunction())
1341 computeIrreducibleMass(
nullptr,
Loops.begin());
1342 if (tryToComputeMassInFunction())
1348bool BlockFrequencyInfoImpl<BT>::needIterativeInference()
const {
1351 if (!
F->getFunction().hasProfileData())
1355 for (
auto L =
Loops.rbegin(),
E =
Loops.rend(); L !=
E; ++L) {
1356 if (
L->isIrreducible())
1362template <
class BT>
void BlockFrequencyInfoImpl<BT>::applyIterativeInference() {
1367 std::vector<const BlockT *> ReachableBlocks;
1368 findReachableBlocks(ReachableBlocks);
1369 if (ReachableBlocks.empty())
1374 DenseMap<const BlockT *, size_t> BlockIndex;
1376 auto Freq = std::vector<Scaled64>(ReachableBlocks.size());
1378 for (
size_t I = 0;
I < ReachableBlocks.size();
I++) {
1379 const BlockT *BB = ReachableBlocks[
I];
1381 Freq[
I] = getFloatingBlockFreq(BB);
1384 assert(!SumFreq.isZero() &&
"empty initial block frequencies");
1386 LLVM_DEBUG(
dbgs() <<
"Applying iterative inference for " <<
F->getName()
1387 <<
" with " << ReachableBlocks.size() <<
" blocks\n");
1390 for (
auto &Value : Freq) {
1396 ProbMatrixType ProbMatrix;
1397 initTransitionProbabilities(ReachableBlocks, BlockIndex, ProbMatrix);
1400 iterativeInference(ProbMatrix, Freq);
1403 for (
const BlockT &BB : *
F) {
1405 if (!
Node.isValid())
1407 if (
auto It = BlockIndex.find(&BB); It != BlockIndex.end())
1408 Freqs[
Node.Index].Scaled = Freq[It->second];
1410 Freqs[
Node.Index].Scaled = Scaled64::getZero();
1415void BlockFrequencyInfoImpl<BT>::iterativeInference(
1416 const ProbMatrixType &ProbMatrix, std::vector<Scaled64> &Freq)
const {
1418 "incorrectly specified precision");
1420 const auto Precision =
1426 << discrepancy(ProbMatrix, Freq).
toString() <<
"\n");
1430 auto Successors = std::vector<std::vector<size_t>>(Freq.size());
1431 for (
size_t I = 0;
I < Freq.size();
I++) {
1432 for (
const auto &Jump : ProbMatrix[
I]) {
1433 Successors[Jump.first].push_back(
I);
1441 auto IsActive = BitVector(Freq.size(),
false);
1442 std::queue<size_t> ActiveSet;
1443 for (
size_t I = 0;
I < Freq.size();
I++) {
1452 while (It++ < MaxIterations && !ActiveSet.empty()) {
1453 size_t I = ActiveSet.front();
1455 IsActive[
I] =
false;
1461 Scaled64 OneMinusSelfProb = Scaled64::getOne();
1462 for (
const auto &Jump : ProbMatrix[
I]) {
1463 if (Jump.first ==
I) {
1464 OneMinusSelfProb -= Jump.second;
1466 NewFreq += Freq[Jump.first] * Jump.second;
1469 if (OneMinusSelfProb != Scaled64::getOne())
1470 NewFreq /= OneMinusSelfProb;
1474 auto Change = Freq[
I] >= NewFreq ? Freq[
I] - NewFreq : NewFreq - Freq[
I];
1475 if (Change > Precision) {
1478 for (
size_t Succ : Successors[
I]) {
1479 if (!IsActive[Succ]) {
1480 ActiveSet.push(Succ);
1481 IsActive[Succ] =
true;
1490 LLVM_DEBUG(
dbgs() <<
" Completed " << It <<
" inference iterations"
1491 <<
format(
" (%0.0f per block)",
double(It) / Freq.size())
1495 << discrepancy(ProbMatrix, Freq).
toString() <<
"\n");
1500void BlockFrequencyInfoImpl<BT>::findReachableBlocks(
1501 std::vector<const BlockT *> &
Blocks)
const {
1504 std::queue<const BlockT *>
Queue;
1505 SmallPtrSet<const BlockT *, 8> Reachable;
1506 const BlockT *
Entry = &
F->front();
1508 Reachable.insert(Entry);
1509 while (!
Queue.empty()) {
1510 const BlockT *SrcBB =
Queue.front();
1512 for (
const BlockT *DstBB : children<const BlockT *>(SrcBB)) {
1513 auto EP = BPI->getEdgeProbability(SrcBB, DstBB);
1516 if (Reachable.insert(DstBB).second)
1523 SmallPtrSet<const BlockT *, 8> InverseReachable;
1524 for (
const BlockT &BB : *
F) {
1526 bool HasSucc = !llvm::children<const BlockT *>(&BB).empty();
1527 if (!HasSucc && Reachable.count(&BB)) {
1529 InverseReachable.insert(&BB);
1532 while (!
Queue.empty()) {
1533 const BlockT *SrcBB =
Queue.front();
1535 for (
const BlockT *DstBB : inverse_children<const BlockT *>(SrcBB)) {
1536 auto EP = BPI->getEdgeProbability(DstBB, SrcBB);
1539 if (InverseReachable.insert(DstBB).second)
1546 for (
const BlockT &BB : *
F) {
1547 if (Reachable.count(&BB) && InverseReachable.count(&BB)) {
1554void BlockFrequencyInfoImpl<BT>::initTransitionProbabilities(
1555 const std::vector<const BlockT *> &
Blocks,
1556 const DenseMap<const BlockT *, size_t> &BlockIndex,
1557 ProbMatrixType &ProbMatrix)
const {
1558 const size_t NumBlocks =
Blocks.size();
1559 auto Succs = std::vector<std::vector<std::pair<size_t, Scaled64>>>(NumBlocks);
1560 auto SumProb = std::vector<Scaled64>(NumBlocks);
1563 for (
size_t Src = 0; Src < NumBlocks; Src++) {
1564 const BlockT *BB =
Blocks[Src];
1565 SmallPtrSet<const BlockT *, 2> UniqueSuccs;
1566 for (
const auto SI : children<const BlockT *>(BB)) {
1568 auto BlockIndexIt = BlockIndex.find(SI);
1569 if (BlockIndexIt == BlockIndex.end())
1572 if (!UniqueSuccs.insert(SI).second)
1575 auto EP = BPI->getEdgeProbability(BB, SI);
1580 Scaled64::getFraction(EP.getNumerator(), EP.getDenominator());
1581 size_t Dst = BlockIndexIt->second;
1582 Succs[Src].push_back(std::make_pair(Dst, EdgeProb));
1583 SumProb[Src] += EdgeProb;
1588 ProbMatrix = ProbMatrixType(NumBlocks);
1589 for (
size_t Src = 0; Src < NumBlocks; Src++) {
1591 if (Succs[Src].empty())
1594 assert(!SumProb[Src].
isZero() &&
"Zero sum probability of non-exit block");
1595 for (
auto &Jump : Succs[Src]) {
1596 size_t Dst = Jump.first;
1597 Scaled64 Prob = Jump.second;
1598 ProbMatrix[Dst].push_back(std::make_pair(Src, Prob / SumProb[Src]));
1603 size_t EntryIdx = BlockIndex.find(&
F->front())->second;
1604 for (
size_t Src = 0; Src < NumBlocks; Src++) {
1605 if (Succs[Src].empty()) {
1606 ProbMatrix[EntryIdx].push_back(std::make_pair(Src, Scaled64::getOne()));
1614 const ProbMatrixType &ProbMatrix,
const std::vector<Scaled64> &Freq)
const {
1615 assert(Freq[0] > 0 &&
"Incorrectly computed frequency of the entry block");
1616 Scaled64 Discrepancy;
1617 for (
size_t I = 0;
I < ProbMatrix.size();
I++) {
1619 for (
const auto &Jump : ProbMatrix[
I]) {
1620 Sum += Freq[Jump.first] * Jump.second;
1622 Discrepancy += Freq[
I] >= Sum ? Freq[
I] - Sum : Sum - Freq[
I];
1625 return Discrepancy / Freq[0];
1630void BlockFrequencyInfoImpl<BT>::computeIrreducibleMass(
1631 LoopData *OuterLoop, std::list<LoopData>::iterator Insert) {
1633 if (OuterLoop)
dbgs()
1634 <<
"loop: " << getLoopName(*OuterLoop) <<
"\n";
1635 else dbgs() <<
"function\n");
1637 using namespace bfi_detail;
1639 auto addBlockEdges = [&](IrreducibleGraph &
G, IrreducibleGraph::IrrNode &Irr,
1640 const LoopData *OuterLoop) {
1641 const BlockT *BB = RPOT[Irr.Node.Index];
1642 for (
const auto *Succ : children<const BlockT *>(BB))
1643 G.addEdge(Irr,
getNode(Succ), OuterLoop);
1645 IrreducibleGraph
G(*
this, OuterLoop, addBlockEdges);
1647 for (
auto &L : analyzeIrreducible(
G, OuterLoop, Insert))
1648 computeMassInLoop(L);
1652 updateLoopWithIrreducible(*OuterLoop);
1662BlockFrequencyInfoImpl<BT>::propagateMassToSuccessors(LoopData *OuterLoop,
1663 const BlockNode &
Node) {
1667 if (
auto *Loop = Working[
Node.Index].getPackagedLoop()) {
1668 assert(Loop != OuterLoop &&
"Cannot propagate mass in a packaged loop");
1669 if (!addLoopSuccessorsToDist(OuterLoop, *Loop, Dist))
1673 const BlockT *BB = getBlock(
Node);
1674 for (
auto SI = GraphTraits<const BlockT *>::child_begin(BB),
1675 SE = GraphTraits<const BlockT *>::child_end(BB);
1686 distributeMass(
Node, OuterLoop, Dist);
1694 OS <<
"block-frequency-info: " <<
F->getName() <<
"\n";
1695 for (
const BlockT &BB : *
F) {
1697 getFloatingBlockFreq(&BB).print(
OS, 5)
1698 <<
", int = " << getBlockFreq(&BB).getFrequency();
1703 if (std::optional<uint64_t> IrrLoopHeaderWeight =
1704 BB.getIrrLoopHeaderWeight())
1705 OS <<
", irr_loop_header_weight = " << *IrrLoopHeaderWeight;
1720 for (
auto &Entry : Nodes) {
1721 const BlockT *BB = Entry.first;
1723 ValidNodes[BB] = Entry.second.first;
1726 for (
auto &Entry :
Other.Nodes) {
1727 const BlockT *BB = Entry.first;
1729 OtherValidNodes[BB] = Entry.second.first;
1732 unsigned NumValidNodes = ValidNodes.
size();
1733 unsigned NumOtherValidNodes = OtherValidNodes.
size();
1734 if (NumValidNodes != NumOtherValidNodes) {
1736 dbgs() <<
"Number of blocks mismatch: " << NumValidNodes <<
" vs "
1737 << NumOtherValidNodes <<
"\n";
1739 for (
auto &Entry : ValidNodes) {
1740 const BlockT *BB = Entry.first;
1742 if (
auto It = OtherValidNodes.
find(BB); It != OtherValidNodes.
end()) {
1744 const auto &Freq = Freqs[
Node.Index];
1745 const auto &OtherFreq =
Other.Freqs[OtherNode.
Index];
1746 if (Freq.Integer != OtherFreq.Integer) {
1749 << Freq.Integer <<
" vs " << OtherFreq.Integer <<
"\n";
1754 <<
Node.Index <<
" does not exist in Other.\n";
1763 dbgs() <<
"Other\n";
1766 assert(Match &&
"BFI mismatch");
1774template <
class BlockFrequencyInfoT,
class BranchProbabilityInfoT>
1787 return G->getFunction()->getName();
1791 unsigned HotPercentThreshold = 0) {
1793 if (!HotPercentThreshold)
1798 for (
NodeIter I = GTraits::nodes_begin(Graph),
1799 E = GTraits::nodes_end(Graph);
1803 std::max(
MaxFrequency, Graph->getBlockFreq(
N).getFrequency());
1815 OS <<
"color=\"red\"";
1821 GVDAGType GType,
int layout_order = -1) {
1825 if (layout_order != -1)
1826 OS <<
Node->getName() <<
"[" << layout_order <<
"] : ";
1828 OS <<
Node->getName() <<
" : ";
1834 OS << Graph->getBlockFreq(
Node).getFrequency();
1837 auto Count = Graph->getBlockProfileCount(
Node);
1846 "never reach this point.");
1852 const BlockFrequencyInfoT *BFI,
1853 const BranchProbabilityInfoT *BPI,
1854 unsigned HotPercentThreshold = 0) {
1866 if (HotPercentThreshold) {
1871 if (EFreq >= HotFreq) {
1872 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< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
DenseMap< Block *, BlockRelaxAux > Blocks
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
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.
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.
Shared implementation for block frequency analysis.
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
Value handle with callbacks on RAUW and destruction.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
Class to represent profile counts.
Represents a single loop in the control flow graph.
Simple representation of a scaled number.
iterator insert(iterator I, T &&Elt)
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.
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 *, 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.
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)
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)
Function::ProfileCount ProfileCount
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
llvm::cl::opt< unsigned > IterativeBFIMaxIterationsPerBlock
po_iterator< T > po_begin(const T &G)
llvm::cl::opt< bool > UseIterativeBFIInference
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
llvm::cl::opt< bool > CheckBFIUnknownBlockQueries
const char * toString(DWARFSectionKind Kind)
LLVM_ABI Printable printBlockFreq(const BlockFrequencyInfo &BFI, BlockFrequency Freq)
Print the block frequency Freq relative to the current functions entry frequency.
po_iterator< T > po_end(const T &G)
llvm::cl::opt< double > IterativeBFIPrecision
Implement std::hash so that hash_code can be used in STL containers.
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)
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
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)
NodeList::const_iterator members_end() const
NodeList::const_iterator members_begin() const
bool isIrreducible() const
BlockNode getHeader() const
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)
Index of loop information.
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 - This class provides the default implementations of all of the DOTGraphTraits ...
typename GraphType::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)
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)