//===- bolt/Passes/ReorderAlgorithm.cpp - Basic block reordering ----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements classes used by several basic block reordering
// algorithms.
//
//===----------------------------------------------------------------------===//

#include "bolt/Passes/ReorderAlgorithm.h"
#include "bolt/Core/BinaryBasicBlock.h"
#include "bolt/Core/BinaryFunction.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Utils/CodeLayout.h"
#include <queue>
#include <random>
#include <stack>

#undef DEBUG_TYPE
#define DEBUG_TYPE "bolt"

using namespace llvm;
using namespace bolt;

namespace opts {

extern cl::OptionCategory BoltOptCategory;
extern cl::opt<bool> NoThreads;

static cl::opt<unsigned> ColdThreshold(
    "cold-threshold",
    cl::desc("tenths of percents of main entry frequency to use as a "
             "threshold when evaluating whether a basic block is cold "
             "(0 means it is only considered cold if the block has zero "
             "samples). Default: 0 "),
    cl::init(0), cl::ZeroOrMore, cl::Hidden, cl::cat(BoltOptCategory));

static cl::opt<bool> PrintClusters("print-clusters", cl::desc("print clusters"),
                                   cl::Hidden, cl::cat(BoltOptCategory));

cl::opt<uint32_t> RandomSeed("bolt-seed", cl::desc("seed for randomization"),
                             cl::init(42), cl::Hidden,
                             cl::cat(BoltOptCategory));

} // namespace opts

namespace {

template <class T> inline void hashCombine(size_t &Seed, const T &Val) {
  std::hash<T> Hasher;
  Seed ^= Hasher(Val) + 0x9e3779b9 + (Seed << 6) + (Seed >> 2);
}

template <typename A, typename B> struct HashPair {
  size_t operator()(const std::pair<A, B> &Val) const {
    std::hash<A> Hasher;
    size_t Seed = Hasher(Val.first);
    hashCombine(Seed, Val.second);
    return Seed;
  }
};

} // namespace

void ClusterAlgorithm::computeClusterAverageFrequency(const BinaryContext &BC) {
  // Create a separate MCCodeEmitter to allow lock-free execution
  BinaryContext::IndependentCodeEmitter Emitter;
  if (!opts::NoThreads)
    Emitter = BC.createIndependentMCCodeEmitter();

  AvgFreq.resize(Clusters.size(), 0.0);
  for (uint32_t I = 0, E = Clusters.size(); I < E; ++I) {
    double Freq = 0.0;
    uint64_t ClusterSize = 0;
    for (const BinaryBasicBlock *BB : Clusters[I]) {
      if (BB->getNumNonPseudos() > 0) {
        Freq += BB->getExecutionCount();
        // Estimate the size of a block in bytes at run time
        // NOTE: This might be inaccurate
        ClusterSize += BB->estimateSize(Emitter.MCE.get());
      }
    }
    AvgFreq[I] = ClusterSize == 0 ? 0 : Freq / ClusterSize;
  }
}

void ClusterAlgorithm::printClusters() const {
  for (uint32_t I = 0, E = Clusters.size(); I < E; ++I) {
    errs() << "Cluster number " << I;
    if (AvgFreq.size() == Clusters.size())
      errs() << " (frequency: " << AvgFreq[I] << ")";
    errs() << " : ";
    const char *Sep = "";
    for (const BinaryBasicBlock *BB : Clusters[I]) {
      errs() << Sep << BB->getName();
      Sep = ", ";
    }
    errs() << "\n";
  }
}

void ClusterAlgorithm::reset() {
  Clusters.clear();
  ClusterEdges.clear();
  AvgFreq.clear();
}

void GreedyClusterAlgorithm::EdgeTy::print(raw_ostream &OS) const {
  OS << Src->getName() << " -> " << Dst->getName() << ", count: " << Count;
}

size_t GreedyClusterAlgorithm::EdgeHash::operator()(const EdgeTy &E) const {
  HashPair<const BinaryBasicBlock *, const BinaryBasicBlock *> Hasher;
  return Hasher(std::make_pair(E.Src, E.Dst));
}

bool GreedyClusterAlgorithm::EdgeEqual::operator()(const EdgeTy &A,
                                                   const EdgeTy &B) const {
  return A.Src == B.Src && A.Dst == B.Dst;
}

void GreedyClusterAlgorithm::clusterBasicBlocks(BinaryFunction &BF,
                                                bool ComputeEdges) {
  reset();

  // Greedy heuristic implementation for the TSP, applied to BB layout. Try to
  // maximize weight during a path traversing all BBs. In this way, we will
  // convert the hottest branches into fall-throughs.

  // This is the queue of edges from which we will pop edges and use them to
  // cluster basic blocks in a greedy fashion.
  std::vector<EdgeTy> Queue;

  // Initialize inter-cluster weights.
  if (ComputeEdges)
    ClusterEdges.resize(BF.getLayout().block_size());

  // Initialize clusters and edge queue.
  for (BinaryBasicBlock *BB : BF.getLayout().blocks()) {
    // Create a cluster for this BB.
    uint32_t I = Clusters.size();
    Clusters.emplace_back();
    std::vector<BinaryBasicBlock *> &Cluster = Clusters.back();
    Cluster.push_back(BB);
    BBToClusterMap[BB] = I;
    // Populate priority queue with edges.
    auto BI = BB->branch_info_begin();
    for (const BinaryBasicBlock *I : BB->successors()) {
      assert(BI->Count != BinaryBasicBlock::COUNT_NO_PROFILE &&
             "attempted reordering blocks of function with no profile data");
      Queue.emplace_back(EdgeTy(BB, I, BI->Count));
      ++BI;
    }
  }
  // Sort and adjust the edge queue.
  initQueue(Queue, BF);

  // Grow clusters in a greedy fashion.
  while (!Queue.empty()) {
    EdgeTy E = Queue.back();
    Queue.pop_back();

    const BinaryBasicBlock *SrcBB = E.Src;
    const BinaryBasicBlock *DstBB = E.Dst;

    LLVM_DEBUG(dbgs() << "Popped edge "; E.print(dbgs()); dbgs() << "\n");

    // Case 1: BBSrc and BBDst are the same. Ignore this edge
    if (SrcBB == DstBB || DstBB == *BF.getLayout().block_begin()) {
      LLVM_DEBUG(dbgs() << "\tIgnored (same src, dst)\n");
      continue;
    }

    int I = BBToClusterMap[SrcBB];
    int J = BBToClusterMap[DstBB];

    // Case 2: If they are already allocated at the same cluster, just increase
    // the weight of this cluster
    if (I == J) {
      if (ComputeEdges)
        ClusterEdges[I][I] += E.Count;
      LLVM_DEBUG(dbgs() << "\tIgnored (src, dst belong to the same cluster)\n");
      continue;
    }

    std::vector<BinaryBasicBlock *> &ClusterA = Clusters[I];
    std::vector<BinaryBasicBlock *> &ClusterB = Clusters[J];
    if (areClustersCompatible(ClusterA, ClusterB, E)) {
      // Case 3: SrcBB is at the end of a cluster and DstBB is at the start,
      // allowing us to merge two clusters.
      for (const BinaryBasicBlock *BB : ClusterB)
        BBToClusterMap[BB] = I;
      ClusterA.insert(ClusterA.end(), ClusterB.begin(), ClusterB.end());
      ClusterB.clear();
      if (ComputeEdges) {
        // Increase the intra-cluster edge count of cluster A with the count of
        // this edge as well as with the total count of previously visited edges
        // from cluster B cluster A.
        ClusterEdges[I][I] += E.Count;
        ClusterEdges[I][I] += ClusterEdges[J][I];
        // Iterate through all inter-cluster edges and transfer edges targeting
        // cluster B to cluster A.
        for (uint32_t K = 0, E = ClusterEdges.size(); K != E; ++K)
          ClusterEdges[K][I] += ClusterEdges[K][J];
      }
      // Adjust the weights of the remaining edges and re-sort the queue.
      adjustQueue(Queue, BF);
      LLVM_DEBUG(dbgs() << "\tMerged clusters of src, dst\n");
    } else {
      // Case 4: Both SrcBB and DstBB are allocated in positions we cannot
      // merge them. Add the count of this edge to the inter-cluster edge count
      // between clusters A and B to help us decide ordering between these
      // clusters.
      if (ComputeEdges)
        ClusterEdges[I][J] += E.Count;
      LLVM_DEBUG(
          dbgs() << "\tIgnored (src, dst belong to incompatible clusters)\n");
    }
  }
}

void GreedyClusterAlgorithm::reset() {
  ClusterAlgorithm::reset();
  BBToClusterMap.clear();
}

void PHGreedyClusterAlgorithm::initQueue(std::vector<EdgeTy> &Queue,
                                         const BinaryFunction &BF) {
  // Define a comparison function to establish SWO between edges.
  auto Comp = [&BF](const EdgeTy &A, const EdgeTy &B) {
    // With equal weights, prioritize branches with lower index
    // source/destination. This helps to keep original block order for blocks
    // when optimal order cannot be deducted from a profile.
    if (A.Count == B.Count) {
      const signed SrcOrder = BF.getOriginalLayoutRelativeOrder(A.Src, B.Src);
      return (SrcOrder != 0)
                 ? SrcOrder > 0
                 : BF.getOriginalLayoutRelativeOrder(A.Dst, B.Dst) > 0;
    }
    return A.Count < B.Count;
  };

  // Sort edges in increasing profile count order.
  llvm::sort(Queue, Comp);
}

void PHGreedyClusterAlgorithm::adjustQueue(std::vector<EdgeTy> &Queue,
                                           const BinaryFunction &BF) {
  // Nothing to do.
}

bool PHGreedyClusterAlgorithm::areClustersCompatible(const ClusterTy &Front,
                                                     const ClusterTy &Back,
                                                     const EdgeTy &E) const {
  return Front.back() == E.Src && Back.front() == E.Dst;
}

int64_t MinBranchGreedyClusterAlgorithm::calculateWeight(
    const EdgeTy &E, const BinaryFunction &BF) const {
  const BinaryBasicBlock *SrcBB = E.Src;
  const BinaryBasicBlock *DstBB = E.Dst;

  // Initial weight value.
  int64_t W = (int64_t)E.Count;

  // Adjust the weight by taking into account other edges with the same source.
  auto BI = SrcBB->branch_info_begin();
  for (const BinaryBasicBlock *SuccBB : SrcBB->successors()) {
    assert(BI->Count != BinaryBasicBlock::COUNT_NO_PROFILE &&
           "attempted reordering blocks of function with no profile data");
    assert(BI->Count <= std::numeric_limits<int64_t>::max() &&
           "overflow detected");
    // Ignore edges with same source and destination, edges that target the
    // entry block as well as the edge E itself.
    if (SuccBB != SrcBB && SuccBB != *BF.getLayout().block_begin() &&
        SuccBB != DstBB)
      W -= (int64_t)BI->Count;
    ++BI;
  }

  // Adjust the weight by taking into account other edges with the same
  // destination.
  for (const BinaryBasicBlock *PredBB : DstBB->predecessors()) {
    // Ignore edges with same source and destination as well as the edge E
    // itself.
    if (PredBB == DstBB || PredBB == SrcBB)
      continue;
    auto BI = PredBB->branch_info_begin();
    for (const BinaryBasicBlock *SuccBB : PredBB->successors()) {
      if (SuccBB == DstBB)
        break;
      ++BI;
    }
    assert(BI != PredBB->branch_info_end() && "invalid control flow graph");
    assert(BI->Count != BinaryBasicBlock::COUNT_NO_PROFILE &&
           "attempted reordering blocks of function with no profile data");
    assert(BI->Count <= std::numeric_limits<int64_t>::max() &&
           "overflow detected");
    W -= (int64_t)BI->Count;
  }

  return W;
}

void MinBranchGreedyClusterAlgorithm::initQueue(std::vector<EdgeTy> &Queue,
                                                const BinaryFunction &BF) {
  // Initialize edge weights.
  for (const EdgeTy &E : Queue)
    Weight.emplace(std::make_pair(E, calculateWeight(E, BF)));

  // Sort edges in increasing weight order.
  adjustQueue(Queue, BF);
}

void MinBranchGreedyClusterAlgorithm::adjustQueue(std::vector<EdgeTy> &Queue,
                                                  const BinaryFunction &BF) {
  // Define a comparison function to establish SWO between edges.
  auto Comp = [&](const EdgeTy &A, const EdgeTy &B) {
    // With equal weights, prioritize branches with lower index
    // source/destination. This helps to keep original block order for blocks
    // when optimal order cannot be deduced from a profile.
    if (Weight[A] == Weight[B]) {
      const signed SrcOrder = BF.getOriginalLayoutRelativeOrder(A.Src, B.Src);
      return (SrcOrder != 0)
                 ? SrcOrder > 0
                 : BF.getOriginalLayoutRelativeOrder(A.Dst, B.Dst) > 0;
    }
    return Weight[A] < Weight[B];
  };

  // Iterate through all remaining edges to find edges that have their
  // source and destination in the same cluster.
  std::vector<EdgeTy> NewQueue;
  for (const EdgeTy &E : Queue) {
    const BinaryBasicBlock *SrcBB = E.Src;
    const BinaryBasicBlock *DstBB = E.Dst;

    // Case 1: SrcBB and DstBB are the same or DstBB is the entry block. Ignore
    // this edge.
    if (SrcBB == DstBB || DstBB == *BF.getLayout().block_begin()) {
      LLVM_DEBUG(dbgs() << "\tAdjustment: Ignored edge "; E.print(dbgs());
                 dbgs() << " (same src, dst)\n");
      continue;
    }

    int I = BBToClusterMap[SrcBB];
    int J = BBToClusterMap[DstBB];
    std::vector<BinaryBasicBlock *> &ClusterA = Clusters[I];
    std::vector<BinaryBasicBlock *> &ClusterB = Clusters[J];

    // Case 2: They are already allocated at the same cluster or incompatible
    // clusters. Adjust the weights of edges with the same source or
    // destination, so that this edge has no effect on them any more, and ignore
    // this edge. Also increase the intra- (or inter-) cluster edge count.
    if (I == J || !areClustersCompatible(ClusterA, ClusterB, E)) {
      if (!ClusterEdges.empty())
        ClusterEdges[I][J] += E.Count;
      LLVM_DEBUG(dbgs() << "\tAdjustment: Ignored edge "; E.print(dbgs());
                 dbgs() << " (src, dst belong to same cluster or incompatible "
                           "clusters)\n");
      for (const BinaryBasicBlock *SuccBB : SrcBB->successors()) {
        if (SuccBB == DstBB)
          continue;
        auto WI = Weight.find(EdgeTy(SrcBB, SuccBB, 0));
        assert(WI != Weight.end() && "CFG edge not found in Weight map");
        WI->second += (int64_t)E.Count;
      }
      for (const BinaryBasicBlock *PredBB : DstBB->predecessors()) {
        if (PredBB == SrcBB)
          continue;
        auto WI = Weight.find(EdgeTy(PredBB, DstBB, 0));
        assert(WI != Weight.end() && "CFG edge not found in Weight map");
        WI->second += (int64_t)E.Count;
      }
      continue;
    }

    // Case 3: None of the previous cases is true, so just keep this edge in
    // the queue.
    NewQueue.emplace_back(E);
  }

  // Sort remaining edges in increasing weight order.
  Queue.swap(NewQueue);
  llvm::sort(Queue, Comp);
}

bool MinBranchGreedyClusterAlgorithm::areClustersCompatible(
    const ClusterTy &Front, const ClusterTy &Back, const EdgeTy &E) const {
  return Front.back() == E.Src && Back.front() == E.Dst;
}

void MinBranchGreedyClusterAlgorithm::reset() {
  GreedyClusterAlgorithm::reset();
  Weight.clear();
}

void TSPReorderAlgorithm::reorderBasicBlocks(BinaryFunction &BF,
                                             BasicBlockOrder &Order) const {
  std::vector<std::vector<uint64_t>> Weight;
  std::vector<BinaryBasicBlock *> IndexToBB;

  const size_t N = BF.getLayout().block_size();
  assert(N <= std::numeric_limits<uint64_t>::digits &&
         "cannot use TSP solution for sizes larger than bits in uint64_t");

  // Populating weight map and index map
  for (BinaryBasicBlock *BB : BF.getLayout().blocks()) {
    BB->setLayoutIndex(IndexToBB.size());
    IndexToBB.push_back(BB);
  }
  Weight.resize(N);
  for (const BinaryBasicBlock *BB : BF.getLayout().blocks()) {
    auto BI = BB->branch_info_begin();
    Weight[BB->getLayoutIndex()].resize(N);
    for (BinaryBasicBlock *SuccBB : BB->successors()) {
      if (BI->Count != BinaryBasicBlock::COUNT_NO_PROFILE)
        Weight[BB->getLayoutIndex()][SuccBB->getLayoutIndex()] = BI->Count;
      ++BI;
    }
  }

  std::vector<std::vector<int64_t>> DP;
  DP.resize(static_cast<size_t>(1) << N);
  for (std::vector<int64_t> &Elmt : DP)
    Elmt.resize(N, -1);

  // Start with the entry basic block being allocated with cost zero
  DP[1][0] = 0;
  // Walk through TSP solutions using a bitmask to represent state (current set
  // of BBs in the layout)
  uint64_t BestSet = 1;
  uint64_t BestLast = 0;
  int64_t BestWeight = 0;
  for (uint64_t Set = 1; Set < (1ULL << N); ++Set) {
    // Traverse each possibility of Last BB visited in this layout
    for (uint64_t Last = 0; Last < N; ++Last) {
      // Case 1: There is no possible layout with this BB as Last
      if (DP[Set][Last] == -1)
        continue;

      // Case 2: There is a layout with this Set and this Last, and we try
      // to expand this set with New
      for (uint64_t New = 1; New < N; ++New) {
        // Case 2a: BB "New" is already in this Set
        if ((Set & (1ULL << New)) != 0)
          continue;

        // Case 2b: BB "New" is not in this set and we add it to this Set and
        // record total weight of this layout with "New" as the last BB.
        uint64_t NewSet = (Set | (1ULL << New));
        if (DP[NewSet][New] == -1)
          DP[NewSet][New] = DP[Set][Last] + (int64_t)Weight[Last][New];
        DP[NewSet][New] = std::max(DP[NewSet][New],
                                   DP[Set][Last] + (int64_t)Weight[Last][New]);

        if (DP[NewSet][New] > BestWeight) {
          BestWeight = DP[NewSet][New];
          BestSet = NewSet;
          BestLast = New;
        }
      }
    }
  }

  // Define final function layout based on layout that maximizes weight
  uint64_t Last = BestLast;
  uint64_t Set = BestSet;
  BitVector Visited;
  Visited.resize(N);
  Visited[Last] = true;
  Order.push_back(IndexToBB[Last]);
  Set = Set & ~(1ULL << Last);
  while (Set != 0) {
    int64_t Best = -1;
    uint64_t NewLast;
    for (uint64_t I = 0; I < N; ++I) {
      if (DP[Set][I] == -1)
        continue;
      int64_t AdjWeight = Weight[I][Last] > 0 ? Weight[I][Last] : 0;
      if (DP[Set][I] + AdjWeight > Best) {
        NewLast = I;
        Best = DP[Set][I] + AdjWeight;
      }
    }
    Last = NewLast;
    Visited[Last] = true;
    Order.push_back(IndexToBB[Last]);
    Set = Set & ~(1ULL << Last);
  }
  std::reverse(Order.begin(), Order.end());

  // Finalize layout with BBs that weren't assigned to the layout using the
  // input layout.
  for (BinaryBasicBlock *BB : BF.getLayout().blocks())
    if (Visited[BB->getLayoutIndex()] == false)
      Order.push_back(BB);
}

void ExtTSPReorderAlgorithm::reorderBasicBlocks(BinaryFunction &BF,
                                                BasicBlockOrder &Order) const {
  if (BF.getLayout().block_empty())
    return;

  // Do not change layout of functions w/o profile information
  if (!BF.hasValidProfile() || BF.getLayout().block_size() <= 2) {
    for (BinaryBasicBlock *BB : BF.getLayout().blocks())
      Order.push_back(BB);
    return;
  }

  // Create a separate MCCodeEmitter to allow lock-free execution
  BinaryContext::IndependentCodeEmitter Emitter;
  if (!opts::NoThreads)
    Emitter = BF.getBinaryContext().createIndependentMCCodeEmitter();

  // Initialize CFG nodes and their data
  std::vector<uint64_t> BlockSizes;
  std::vector<uint64_t> BlockCounts;
  BasicBlockOrder OrigOrder;
  BF.getLayout().updateLayoutIndices();
  size_t BFBlockSize = BF.getLayout().block_size();
  BlockSizes.reserve(BFBlockSize);
  BlockCounts.reserve(BFBlockSize);
  OrigOrder.reserve(BFBlockSize);
  for (BinaryBasicBlock *BB : BF.getLayout().blocks()) {
    uint64_t Size = std::max<uint64_t>(BB->estimateSize(Emitter.MCE.get()), 1);
    BlockSizes.push_back(Size);
    BlockCounts.push_back(BB->getKnownExecutionCount());
    OrigOrder.push_back(BB);
  }

  // Initialize CFG edges
  std::vector<codelayout::EdgeCount> JumpCounts;
  for (BinaryBasicBlock *BB : BF.getLayout().blocks()) {
    auto BI = BB->branch_info_begin();
    for (BinaryBasicBlock *SuccBB : BB->successors()) {
      assert(BI->Count != BinaryBasicBlock::COUNT_NO_PROFILE &&
             "missing profile for a jump");
      JumpCounts.push_back(
          {BB->getLayoutIndex(), SuccBB->getLayoutIndex(), BI->Count});
      ++BI;
    }
  }

  // Run the layout algorithm
  auto Result =
      codelayout::computeExtTspLayout(BlockSizes, BlockCounts, JumpCounts);
  Order.reserve(BF.getLayout().block_size());
  for (uint64_t R : Result)
    Order.push_back(OrigOrder[R]);
}

void OptimizeReorderAlgorithm::reorderBasicBlocks(
    BinaryFunction &BF, BasicBlockOrder &Order) const {
  if (BF.getLayout().block_empty())
    return;

  // Cluster basic blocks.
  CAlgo->clusterBasicBlocks(BF);

  if (opts::PrintClusters)
    CAlgo->printClusters();

  // Arrange basic blocks according to clusters.
  for (ClusterAlgorithm::ClusterTy &Cluster : CAlgo->Clusters)
    Order.insert(Order.end(), Cluster.begin(), Cluster.end());
}

void OptimizeBranchReorderAlgorithm::reorderBasicBlocks(
    BinaryFunction &BF, BasicBlockOrder &Order) const {
  if (BF.getLayout().block_empty())
    return;

  // Cluster basic blocks.
  CAlgo->clusterBasicBlocks(BF, /* ComputeEdges = */ true);
  std::vector<ClusterAlgorithm::ClusterTy> &Clusters = CAlgo->Clusters;
  std::vector<std::unordered_map<uint32_t, uint64_t>> &ClusterEdges =
      CAlgo->ClusterEdges;

  // Compute clusters' average frequencies.
  CAlgo->computeClusterAverageFrequency(BF.getBinaryContext());
  std::vector<double> &AvgFreq = CAlgo->AvgFreq;

  if (opts::PrintClusters)
    CAlgo->printClusters();

  // Cluster layout order
  std::vector<uint32_t> ClusterOrder;

  // Do a topological sort for clusters, prioritizing frequently-executed BBs
  // during the traversal.
  std::stack<uint32_t> Stack;
  std::vector<uint32_t> Status;
  std::vector<uint32_t> Parent;
  Status.resize(Clusters.size(), 0);
  Parent.resize(Clusters.size(), 0);
  constexpr uint32_t STACKED = 1;
  constexpr uint32_t VISITED = 2;
  Status[0] = STACKED;
  Stack.push(0);
  while (!Stack.empty()) {
    uint32_t I = Stack.top();
    if (!(Status[I] & VISITED)) {
      Status[I] |= VISITED;
      // Order successors by weight
      auto ClusterComp = [&ClusterEdges, I](uint32_t A, uint32_t B) {
        return ClusterEdges[I][A] > ClusterEdges[I][B];
      };
      std::priority_queue<uint32_t, std::vector<uint32_t>,
                          decltype(ClusterComp)>
          SuccQueue(ClusterComp);
      for (std::pair<const uint32_t, uint64_t> &Target : ClusterEdges[I]) {
        if (Target.second > 0 && !(Status[Target.first] & STACKED) &&
            !Clusters[Target.first].empty()) {
          Parent[Target.first] = I;
          Status[Target.first] = STACKED;
          SuccQueue.push(Target.first);
        }
      }
      while (!SuccQueue.empty()) {
        Stack.push(SuccQueue.top());
        SuccQueue.pop();
      }
      continue;
    }
    // Already visited this node
    Stack.pop();
    ClusterOrder.push_back(I);
  }
  std::reverse(ClusterOrder.begin(), ClusterOrder.end());
  // Put unreachable clusters at the end
  for (uint32_t I = 0, E = Clusters.size(); I < E; ++I)
    if (!(Status[I] & VISITED) && !Clusters[I].empty())
      ClusterOrder.push_back(I);

  // Sort nodes with equal precedence
  auto Beg = ClusterOrder.begin();
  // Don't reorder the first cluster, which contains the function entry point
  ++Beg;
  std::stable_sort(Beg, ClusterOrder.end(),
                   [&AvgFreq, &Parent](uint32_t A, uint32_t B) {
                     uint32_t P = Parent[A];
                     while (Parent[P] != 0) {
                       if (Parent[P] == B)
                         return false;
                       P = Parent[P];
                     }
                     P = Parent[B];
                     while (Parent[P] != 0) {
                       if (Parent[P] == A)
                         return true;
                       P = Parent[P];
                     }
                     return AvgFreq[A] > AvgFreq[B];
                   });

  if (opts::PrintClusters) {
    errs() << "New cluster order: ";
    const char *Sep = "";
    for (uint32_t O : ClusterOrder) {
      errs() << Sep << O;
      Sep = ", ";
    }
    errs() << '\n';
  }

  // Arrange basic blocks according to cluster order.
  for (uint32_t ClusterIndex : ClusterOrder) {
    ClusterAlgorithm::ClusterTy &Cluster = Clusters[ClusterIndex];
    Order.insert(Order.end(), Cluster.begin(), Cluster.end());
  }
}

void OptimizeCacheReorderAlgorithm::reorderBasicBlocks(
    BinaryFunction &BF, BasicBlockOrder &Order) const {
  if (BF.getLayout().block_empty())
    return;

  const uint64_t ColdThreshold =
      opts::ColdThreshold *
      (*BF.getLayout().block_begin())->getExecutionCount() / 1000;

  // Cluster basic blocks.
  CAlgo->clusterBasicBlocks(BF);
  std::vector<ClusterAlgorithm::ClusterTy> &Clusters = CAlgo->Clusters;

  // Compute clusters' average frequencies.
  CAlgo->computeClusterAverageFrequency(BF.getBinaryContext());
  std::vector<double> &AvgFreq = CAlgo->AvgFreq;

  if (opts::PrintClusters)
    CAlgo->printClusters();

  // Cluster layout order
  std::vector<uint32_t> ClusterOrder;

  // Order clusters based on average instruction execution frequency
  for (uint32_t I = 0, E = Clusters.size(); I < E; ++I)
    if (!Clusters[I].empty())
      ClusterOrder.push_back(I);
  // Don't reorder the first cluster, which contains the function entry point
  std::stable_sort(
      std::next(ClusterOrder.begin()), ClusterOrder.end(),
      [&AvgFreq](uint32_t A, uint32_t B) { return AvgFreq[A] > AvgFreq[B]; });

  if (opts::PrintClusters) {
    errs() << "New cluster order: ";
    const char *Sep = "";
    for (uint32_t O : ClusterOrder) {
      errs() << Sep << O;
      Sep = ", ";
    }
    errs() << '\n';
  }

  // Arrange basic blocks according to cluster order.
  for (uint32_t ClusterIndex : ClusterOrder) {
    ClusterAlgorithm::ClusterTy &Cluster = Clusters[ClusterIndex];
    Order.insert(Order.end(), Cluster.begin(), Cluster.end());
    // Force zero execution count on clusters that do not meet the cut off
    // specified by --cold-threshold.
    if (AvgFreq[ClusterIndex] < static_cast<double>(ColdThreshold))
      for (BinaryBasicBlock *BBPtr : Cluster)
        BBPtr->setExecutionCount(0);
  }
}

void ReverseReorderAlgorithm::reorderBasicBlocks(BinaryFunction &BF,
                                                 BasicBlockOrder &Order) const {
  if (BF.getLayout().block_empty())
    return;

  BinaryBasicBlock *FirstBB = *BF.getLayout().block_begin();
  Order.push_back(FirstBB);
  for (auto RLI = BF.getLayout().block_rbegin(); *RLI != FirstBB; ++RLI)
    Order.push_back(*RLI);
}

void RandomClusterReorderAlgorithm::reorderBasicBlocks(
    BinaryFunction &BF, BasicBlockOrder &Order) const {
  if (BF.getLayout().block_empty())
    return;

  // Cluster basic blocks.
  CAlgo->clusterBasicBlocks(BF);
  std::vector<ClusterAlgorithm::ClusterTy> &Clusters = CAlgo->Clusters;

  if (opts::PrintClusters)
    CAlgo->printClusters();

  // Cluster layout order
  std::vector<uint32_t> ClusterOrder;

  // Order clusters based on average instruction execution frequency
  for (uint32_t I = 0, E = Clusters.size(); I < E; ++I)
    if (!Clusters[I].empty())
      ClusterOrder.push_back(I);

  std::shuffle(std::next(ClusterOrder.begin()), ClusterOrder.end(),
               std::default_random_engine(opts::RandomSeed.getValue()));

  if (opts::PrintClusters) {
    errs() << "New cluster order: ";
    const char *Sep = "";
    for (uint32_t O : ClusterOrder) {
      errs() << Sep << O;
      Sep = ", ";
    }
    errs() << '\n';
  }

  // Arrange basic blocks according to cluster order.
  for (uint32_t ClusterIndex : ClusterOrder) {
    ClusterAlgorithm::ClusterTy &Cluster = Clusters[ClusterIndex];
    Order.insert(Order.end(), Cluster.begin(), Cluster.end());
  }
}
