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<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; }
 
 
 1067template <
class BFIImplT>
 
 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);
 
 1148    It->second = {NewNode, BFICallbackVH(BB, 
this)};
 
 1149    Freqs.emplace_back();
 
 
 1154template <
class BT> 
void BlockFrequencyInfoImpl<BT>::initializeRPOT() {
 
 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());
 
 1172  for (
size_t Index = 0; 
Index < RPOT.size(); ++
Index)
 
 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;
 
 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());
 
 1204  for (
size_t Index = 0; 
Index < RPOT.size(); ++
Index) {
 
 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]);
 
 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) {
 
 1249  if (
Loop.isIrreducible()) {
 
 1252    unsigned NumHeadersWithWeight = 0;
 
 1253    std::optional<uint64_t> MinHeaderWeight;
 
 1256    for (uint32_t 
H = 0; 
H < 
Loop.NumHeaders; ++
H) {
 
 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();
 
 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())
 
 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;
 
 1506  const BlockT *
Entry = &
F->front();
 
 1508  Reachable.insert(Entry);
 
 1509  while (!
Queue.empty()) {
 
 1510    const BlockT *SrcBB = 
Queue.front();
 
 1513      auto EP = BPI->getEdgeProbability(SrcBB, DstBB);
 
 1516      if (Reachable.insert(DstBB).second)
 
 1524  for (
const BlockT &BB : *
F) {
 
 1527    if (!HasSucc && Reachable.count(&BB)) {
 
 1529      InverseReachable.insert(&BB);
 
 1532  while (!
Queue.empty()) {
 
 1533    const BlockT *SrcBB = 
Queue.front();
 
 1536      auto EP = BPI->getEdgeProbability(DstBB, SrcBB);
 
 1539      if (InverseReachable.insert(DstBB).second)
 
 1545  Blocks.reserve(
F->size());
 
 1546  for (
const BlockT &BB : *
F) {
 
 1547    if (Reachable.count(&BB) && InverseReachable.count(&BB)) {
 
 1548      Blocks.push_back(&BB);
 
 1554void BlockFrequencyInfoImpl<BT>::initTransitionProbabilities(
 
 1555    const std::vector<const BlockT *> &Blocks,
 
 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];
 
 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");
 
 1639  auto addBlockEdges = [&](IrreducibleGraph &
G, IrreducibleGraph::IrrNode &Irr,
 
 1640                           const LoopData *OuterLoop) {
 
 1641    const BlockT *BB = RPOT[Irr.Node.Index];
 
 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);
 
 1686  distributeMass(Node, OuterLoop, Dist);
 
 1694  OS << 
"block-frequency-info: " << F->getName() << 
"\n";
 
 1695  for (
const BlockT &BB : *F) {
 
 1701            F->getFunction(), getNode(&BB)))
 
 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()) {
 
 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)
 
 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< 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.
 
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton 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 *, 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)
 
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.
 
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.
 
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.
 
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