//===- MachineScheduler.cpp - Machine Instruction Scheduler ---------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// MachineScheduler schedules machine instructions after phi elimination. It
// preserves LiveIntervals so it can be invoked before register allocation.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/EquivalenceClasses.h"
#include "llvm/ADT/PriorityQueue.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachinePassRegistry.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/RegisterPressure.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
#include "llvm/CodeGen/ScheduleDAGMutation.h"
#include "llvm/CodeGen/ScheduleDFS.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSchedule.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGenTypes/MachineValueType.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <limits>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace llvm;

#define DEBUG_TYPE "machine-scheduler"

STATISTIC(NumInstrsInSourceOrderPreRA,
          "Number of instructions in source order after pre-RA scheduling");
STATISTIC(NumInstrsInSourceOrderPostRA,
          "Number of instructions in source order after post-RA scheduling");
STATISTIC(NumInstrsScheduledPreRA,
          "Number of instructions scheduled by pre-RA scheduler");
STATISTIC(NumInstrsScheduledPostRA,
          "Number of instructions scheduled by post-RA scheduler");
STATISTIC(NumClustered, "Number of load/store pairs clustered");

STATISTIC(NumTopPreRA,
          "Number of scheduling units chosen from top queue pre-RA");
STATISTIC(NumBotPreRA,
          "Number of scheduling units chosen from bottom queue pre-RA");
STATISTIC(NumNoCandPreRA,
          "Number of scheduling units chosen for NoCand heuristic pre-RA");
STATISTIC(NumOnly1PreRA,
          "Number of scheduling units chosen for Only1 heuristic pre-RA");
STATISTIC(NumPhysRegPreRA,
          "Number of scheduling units chosen for PhysReg heuristic pre-RA");
STATISTIC(NumRegExcessPreRA,
          "Number of scheduling units chosen for RegExcess heuristic pre-RA");
STATISTIC(NumRegCriticalPreRA,
          "Number of scheduling units chosen for RegCritical heuristic pre-RA");
STATISTIC(NumStallPreRA,
          "Number of scheduling units chosen for Stall heuristic pre-RA");
STATISTIC(NumClusterPreRA,
          "Number of scheduling units chosen for Cluster heuristic pre-RA");
STATISTIC(NumWeakPreRA,
          "Number of scheduling units chosen for Weak heuristic pre-RA");
STATISTIC(NumRegMaxPreRA,
          "Number of scheduling units chosen for RegMax heuristic pre-RA");
STATISTIC(
    NumResourceReducePreRA,
    "Number of scheduling units chosen for ResourceReduce heuristic pre-RA");
STATISTIC(
    NumResourceDemandPreRA,
    "Number of scheduling units chosen for ResourceDemand heuristic pre-RA");
STATISTIC(
    NumTopDepthReducePreRA,
    "Number of scheduling units chosen for TopDepthReduce heuristic pre-RA");
STATISTIC(
    NumTopPathReducePreRA,
    "Number of scheduling units chosen for TopPathReduce heuristic pre-RA");
STATISTIC(
    NumBotHeightReducePreRA,
    "Number of scheduling units chosen for BotHeightReduce heuristic pre-RA");
STATISTIC(
    NumBotPathReducePreRA,
    "Number of scheduling units chosen for BotPathReduce heuristic pre-RA");
STATISTIC(NumNodeOrderPreRA,
          "Number of scheduling units chosen for NodeOrder heuristic pre-RA");
STATISTIC(NumFirstValidPreRA,
          "Number of scheduling units chosen for FirstValid heuristic pre-RA");

STATISTIC(NumTopPostRA,
          "Number of scheduling units chosen from top queue post-RA");
STATISTIC(NumBotPostRA,
          "Number of scheduling units chosen from bottom queue post-RA");
STATISTIC(NumNoCandPostRA,
          "Number of scheduling units chosen for NoCand heuristic post-RA");
STATISTIC(NumOnly1PostRA,
          "Number of scheduling units chosen for Only1 heuristic post-RA");
STATISTIC(NumPhysRegPostRA,
          "Number of scheduling units chosen for PhysReg heuristic post-RA");
STATISTIC(NumRegExcessPostRA,
          "Number of scheduling units chosen for RegExcess heuristic post-RA");
STATISTIC(
    NumRegCriticalPostRA,
    "Number of scheduling units chosen for RegCritical heuristic post-RA");
STATISTIC(NumStallPostRA,
          "Number of scheduling units chosen for Stall heuristic post-RA");
STATISTIC(NumClusterPostRA,
          "Number of scheduling units chosen for Cluster heuristic post-RA");
STATISTIC(NumWeakPostRA,
          "Number of scheduling units chosen for Weak heuristic post-RA");
STATISTIC(NumRegMaxPostRA,
          "Number of scheduling units chosen for RegMax heuristic post-RA");
STATISTIC(
    NumResourceReducePostRA,
    "Number of scheduling units chosen for ResourceReduce heuristic post-RA");
STATISTIC(
    NumResourceDemandPostRA,
    "Number of scheduling units chosen for ResourceDemand heuristic post-RA");
STATISTIC(
    NumTopDepthReducePostRA,
    "Number of scheduling units chosen for TopDepthReduce heuristic post-RA");
STATISTIC(
    NumTopPathReducePostRA,
    "Number of scheduling units chosen for TopPathReduce heuristic post-RA");
STATISTIC(
    NumBotHeightReducePostRA,
    "Number of scheduling units chosen for BotHeightReduce heuristic post-RA");
STATISTIC(
    NumBotPathReducePostRA,
    "Number of scheduling units chosen for BotPathReduce heuristic post-RA");
STATISTIC(NumNodeOrderPostRA,
          "Number of scheduling units chosen for NodeOrder heuristic post-RA");
STATISTIC(NumFirstValidPostRA,
          "Number of scheduling units chosen for FirstValid heuristic post-RA");

namespace llvm {

cl::opt<MISched::Direction> PreRADirection(
    "misched-prera-direction", cl::Hidden,
    cl::desc("Pre reg-alloc list scheduling direction"),
    cl::init(MISched::Unspecified),
    cl::values(
        clEnumValN(MISched::TopDown, "topdown",
                   "Force top-down pre reg-alloc list scheduling"),
        clEnumValN(MISched::BottomUp, "bottomup",
                   "Force bottom-up pre reg-alloc list scheduling"),
        clEnumValN(MISched::Bidirectional, "bidirectional",
                   "Force bidirectional pre reg-alloc list scheduling")));

static cl::opt<MISched::Direction> PostRADirection(
    "misched-postra-direction", cl::Hidden,
    cl::desc("Post reg-alloc list scheduling direction"),
    cl::init(MISched::Unspecified),
    cl::values(
        clEnumValN(MISched::TopDown, "topdown",
                   "Force top-down post reg-alloc list scheduling"),
        clEnumValN(MISched::BottomUp, "bottomup",
                   "Force bottom-up post reg-alloc list scheduling"),
        clEnumValN(MISched::Bidirectional, "bidirectional",
                   "Force bidirectional post reg-alloc list scheduling")));

static cl::opt<bool>
    DumpCriticalPathLength("misched-dcpl", cl::Hidden,
                           cl::desc("Print critical path length to stdout"));

cl::opt<bool> VerifyScheduling(
    "verify-misched", cl::Hidden,
    cl::desc("Verify machine instrs before and after machine scheduling"));

#ifndef NDEBUG
cl::opt<bool> ViewMISchedDAGs(
    "view-misched-dags", cl::Hidden,
    cl::desc("Pop up a window to show MISched dags after they are processed"));
cl::opt<bool> PrintDAGs("misched-print-dags", cl::Hidden,
                        cl::desc("Print schedule DAGs"));
cl::opt<bool> MISchedDumpReservedCycles(
    "misched-dump-reserved-cycles", cl::Hidden, cl::init(false),
    cl::desc("Dump resource usage at schedule boundary."));
cl::opt<bool> MischedDetailResourceBooking(
    "misched-detail-resource-booking", cl::Hidden, cl::init(false),
    cl::desc("Show details of invoking getNextResoufceCycle."));
#else
const bool ViewMISchedDAGs = false;
const bool PrintDAGs = false;
const bool MischedDetailResourceBooking = false;
#ifdef LLVM_ENABLE_DUMP
const bool MISchedDumpReservedCycles = false;
#endif // LLVM_ENABLE_DUMP
#endif // NDEBUG

} // end namespace llvm

#ifndef NDEBUG
/// In some situations a few uninteresting nodes depend on nearly all other
/// nodes in the graph, provide a cutoff to hide them.
static cl::opt<unsigned> ViewMISchedCutoff("view-misched-cutoff", cl::Hidden,
  cl::desc("Hide nodes with more predecessor/successor than cutoff"));

static cl::opt<unsigned> MISchedCutoff("misched-cutoff", cl::Hidden,
  cl::desc("Stop scheduling after N instructions"), cl::init(~0U));

static cl::opt<std::string> SchedOnlyFunc("misched-only-func", cl::Hidden,
  cl::desc("Only schedule this function"));
static cl::opt<unsigned> SchedOnlyBlock("misched-only-block", cl::Hidden,
                                        cl::desc("Only schedule this MBB#"));
#endif // NDEBUG

/// Avoid quadratic complexity in unusually large basic blocks by limiting the
/// size of the ready lists.
static cl::opt<unsigned> ReadyListLimit("misched-limit", cl::Hidden,
  cl::desc("Limit ready list to N instructions"), cl::init(256));

static cl::opt<bool> EnableRegPressure("misched-regpressure", cl::Hidden,
  cl::desc("Enable register pressure scheduling."), cl::init(true));

static cl::opt<bool> EnableCyclicPath("misched-cyclicpath", cl::Hidden,
  cl::desc("Enable cyclic critical path analysis."), cl::init(true));

static cl::opt<bool> EnableMemOpCluster("misched-cluster", cl::Hidden,
                                        cl::desc("Enable memop clustering."),
                                        cl::init(true));
static cl::opt<bool>
    ForceFastCluster("force-fast-cluster", cl::Hidden,
                     cl::desc("Switch to fast cluster algorithm with the lost "
                              "of some fusion opportunities"),
                     cl::init(false));
static cl::opt<unsigned>
    FastClusterThreshold("fast-cluster-threshold", cl::Hidden,
                         cl::desc("The threshold for fast cluster"),
                         cl::init(1000));

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
static cl::opt<bool> MISchedDumpScheduleTrace(
    "misched-dump-schedule-trace", cl::Hidden, cl::init(false),
    cl::desc("Dump resource usage at schedule boundary."));
static cl::opt<unsigned>
    HeaderColWidth("misched-dump-schedule-trace-col-header-width", cl::Hidden,
                   cl::desc("Set width of the columns with "
                            "the resources and schedule units"),
                   cl::init(19));
static cl::opt<unsigned>
    ColWidth("misched-dump-schedule-trace-col-width", cl::Hidden,
             cl::desc("Set width of the columns showing resource booking."),
             cl::init(5));
static cl::opt<bool> MISchedSortResourcesInTrace(
    "misched-sort-resources-in-trace", cl::Hidden, cl::init(true),
    cl::desc("Sort the resources printed in the dump trace"));
#endif

static cl::opt<unsigned>
    MIResourceCutOff("misched-resource-cutoff", cl::Hidden,
                     cl::desc("Number of intervals to track"), cl::init(10));

// DAG subtrees must have at least this many nodes.
static const unsigned MinSubtreeSize = 8;

// Pin the vtables to this file.
void MachineSchedStrategy::anchor() {}

void ScheduleDAGMutation::anchor() {}

//===----------------------------------------------------------------------===//
// Machine Instruction Scheduling Pass and Registry
//===----------------------------------------------------------------------===//

MachineSchedContext::MachineSchedContext() {
  RegClassInfo = new RegisterClassInfo();
}

MachineSchedContext::~MachineSchedContext() {
  delete RegClassInfo;
}

namespace llvm {
namespace impl_detail {

/// Base class for the machine scheduler classes.
class MachineSchedulerBase : public MachineSchedContext {
protected:
  void scheduleRegions(ScheduleDAGInstrs &Scheduler, bool FixKillFlags);
};

/// Impl class for MachineScheduler.
class MachineSchedulerImpl : public MachineSchedulerBase {
  // These are only for using MF.verify()
  // remove when verify supports passing in all analyses
  MachineFunctionPass *P = nullptr;
  MachineFunctionAnalysisManager *MFAM = nullptr;

public:
  struct RequiredAnalyses {
    MachineLoopInfo &MLI;
    MachineDominatorTree &MDT;
    AAResults &AA;
    LiveIntervals &LIS;
  };

  MachineSchedulerImpl() {}
  // Migration only
  void setLegacyPass(MachineFunctionPass *P) { this->P = P; }
  void setMFAM(MachineFunctionAnalysisManager *MFAM) { this->MFAM = MFAM; }

  bool run(MachineFunction &MF, const TargetMachine &TM,
           const RequiredAnalyses &Analyses);

protected:
  ScheduleDAGInstrs *createMachineScheduler();
};

/// Impl class for PostMachineScheduler.
class PostMachineSchedulerImpl : public MachineSchedulerBase {
  // These are only for using MF.verify()
  // remove when verify supports passing in all analyses
  MachineFunctionPass *P = nullptr;
  MachineFunctionAnalysisManager *MFAM = nullptr;

public:
  struct RequiredAnalyses {
    MachineLoopInfo &MLI;
    AAResults &AA;
  };
  PostMachineSchedulerImpl() {}
  // Migration only
  void setLegacyPass(MachineFunctionPass *P) { this->P = P; }
  void setMFAM(MachineFunctionAnalysisManager *MFAM) { this->MFAM = MFAM; }

  bool run(MachineFunction &Func, const TargetMachine &TM,
           const RequiredAnalyses &Analyses);

protected:
  ScheduleDAGInstrs *createPostMachineScheduler();
};

} // namespace impl_detail
} // namespace llvm

using impl_detail::MachineSchedulerBase;
using impl_detail::MachineSchedulerImpl;
using impl_detail::PostMachineSchedulerImpl;

namespace {
/// MachineScheduler runs after coalescing and before register allocation.
class MachineSchedulerLegacy : public MachineFunctionPass {
  MachineSchedulerImpl Impl;

public:
  MachineSchedulerLegacy();
  void getAnalysisUsage(AnalysisUsage &AU) const override;
  bool runOnMachineFunction(MachineFunction&) override;

  static char ID; // Class identification, replacement for typeinfo
};

/// PostMachineScheduler runs after shortly before code emission.
class PostMachineSchedulerLegacy : public MachineFunctionPass {
  PostMachineSchedulerImpl Impl;

public:
  PostMachineSchedulerLegacy();
  void getAnalysisUsage(AnalysisUsage &AU) const override;
  bool runOnMachineFunction(MachineFunction &) override;

  static char ID; // Class identification, replacement for typeinfo
};

} // end anonymous namespace

char MachineSchedulerLegacy::ID = 0;

char &llvm::MachineSchedulerID = MachineSchedulerLegacy::ID;

INITIALIZE_PASS_BEGIN(MachineSchedulerLegacy, DEBUG_TYPE,
                      "Machine Instruction Scheduler", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
INITIALIZE_PASS_END(MachineSchedulerLegacy, DEBUG_TYPE,
                    "Machine Instruction Scheduler", false, false)

MachineSchedulerLegacy::MachineSchedulerLegacy() : MachineFunctionPass(ID) {
  initializeMachineSchedulerLegacyPass(*PassRegistry::getPassRegistry());
}

void MachineSchedulerLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesCFG();
  AU.addRequired<MachineDominatorTreeWrapperPass>();
  AU.addRequired<MachineLoopInfoWrapperPass>();
  AU.addRequired<AAResultsWrapperPass>();
  AU.addRequired<TargetPassConfig>();
  AU.addRequired<SlotIndexesWrapperPass>();
  AU.addPreserved<SlotIndexesWrapperPass>();
  AU.addRequired<LiveIntervalsWrapperPass>();
  AU.addPreserved<LiveIntervalsWrapperPass>();
  MachineFunctionPass::getAnalysisUsage(AU);
}

char PostMachineSchedulerLegacy::ID = 0;

char &llvm::PostMachineSchedulerID = PostMachineSchedulerLegacy::ID;

INITIALIZE_PASS_BEGIN(PostMachineSchedulerLegacy, "postmisched",
                      "PostRA Machine Instruction Scheduler", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(PostMachineSchedulerLegacy, "postmisched",
                    "PostRA Machine Instruction Scheduler", false, false)

PostMachineSchedulerLegacy::PostMachineSchedulerLegacy()
    : MachineFunctionPass(ID) {
  initializePostMachineSchedulerLegacyPass(*PassRegistry::getPassRegistry());
}

void PostMachineSchedulerLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesCFG();
  AU.addRequired<MachineDominatorTreeWrapperPass>();
  AU.addRequired<MachineLoopInfoWrapperPass>();
  AU.addRequired<AAResultsWrapperPass>();
  AU.addRequired<TargetPassConfig>();
  MachineFunctionPass::getAnalysisUsage(AU);
}

MachinePassRegistry<MachineSchedRegistry::ScheduleDAGCtor>
    MachineSchedRegistry::Registry;

/// A dummy default scheduler factory indicates whether the scheduler
/// is overridden on the command line.
static ScheduleDAGInstrs *useDefaultMachineSched(MachineSchedContext *C) {
  return nullptr;
}

/// MachineSchedOpt allows command line selection of the scheduler.
static cl::opt<MachineSchedRegistry::ScheduleDAGCtor, false,
               RegisterPassParser<MachineSchedRegistry>>
MachineSchedOpt("misched",
                cl::init(&useDefaultMachineSched), cl::Hidden,
                cl::desc("Machine instruction scheduler to use"));

static MachineSchedRegistry
DefaultSchedRegistry("default", "Use the target's default scheduler choice.",
                     useDefaultMachineSched);

static cl::opt<bool> EnableMachineSched(
    "enable-misched",
    cl::desc("Enable the machine instruction scheduling pass."), cl::init(true),
    cl::Hidden);

static cl::opt<bool> EnablePostRAMachineSched(
    "enable-post-misched",
    cl::desc("Enable the post-ra machine instruction scheduling pass."),
    cl::init(true), cl::Hidden);

/// Decrement this iterator until reaching the top or a non-debug instr.
static MachineBasicBlock::const_iterator
priorNonDebug(MachineBasicBlock::const_iterator I,
              MachineBasicBlock::const_iterator Beg) {
  assert(I != Beg && "reached the top of the region, cannot decrement");
  while (--I != Beg) {
    if (!I->isDebugOrPseudoInstr())
      break;
  }
  return I;
}

/// Non-const version.
static MachineBasicBlock::iterator
priorNonDebug(MachineBasicBlock::iterator I,
              MachineBasicBlock::const_iterator Beg) {
  return priorNonDebug(MachineBasicBlock::const_iterator(I), Beg)
      .getNonConstIterator();
}

/// If this iterator is a debug value, increment until reaching the End or a
/// non-debug instruction.
static MachineBasicBlock::const_iterator
nextIfDebug(MachineBasicBlock::const_iterator I,
            MachineBasicBlock::const_iterator End) {
  for(; I != End; ++I) {
    if (!I->isDebugOrPseudoInstr())
      break;
  }
  return I;
}

/// Non-const version.
static MachineBasicBlock::iterator
nextIfDebug(MachineBasicBlock::iterator I,
            MachineBasicBlock::const_iterator End) {
  return nextIfDebug(MachineBasicBlock::const_iterator(I), End)
      .getNonConstIterator();
}

/// Instantiate a ScheduleDAGInstrs that will be owned by the caller.
ScheduleDAGInstrs *MachineSchedulerImpl::createMachineScheduler() {
  // Select the scheduler, or set the default.
  MachineSchedRegistry::ScheduleDAGCtor Ctor = MachineSchedOpt;
  if (Ctor != useDefaultMachineSched)
    return Ctor(this);

  // Get the default scheduler set by the target for this function.
  ScheduleDAGInstrs *Scheduler = TM->createMachineScheduler(this);
  if (Scheduler)
    return Scheduler;

  // Default to GenericScheduler.
  return createSchedLive(this);
}

bool MachineSchedulerImpl::run(MachineFunction &Func, const TargetMachine &TM,
                               const RequiredAnalyses &Analyses) {
  MF = &Func;
  MLI = &Analyses.MLI;
  MDT = &Analyses.MDT;
  this->TM = &TM;
  AA = &Analyses.AA;
  LIS = &Analyses.LIS;

  if (VerifyScheduling) {
    LLVM_DEBUG(LIS->dump());
    const char *MSchedBanner = "Before machine scheduling.";
    if (P)
      MF->verify(P, MSchedBanner, &errs());
    else
      MF->verify(*MFAM, MSchedBanner, &errs());
  }
  RegClassInfo->runOnMachineFunction(*MF);

  // Instantiate the selected scheduler for this target, function, and
  // optimization level.
  std::unique_ptr<ScheduleDAGInstrs> Scheduler(createMachineScheduler());
  scheduleRegions(*Scheduler, false);

  LLVM_DEBUG(LIS->dump());
  if (VerifyScheduling) {
    const char *MSchedBanner = "After machine scheduling.";
    if (P)
      MF->verify(P, MSchedBanner, &errs());
    else
      MF->verify(*MFAM, MSchedBanner, &errs());
  }
  return true;
}

/// Instantiate a ScheduleDAGInstrs for PostRA scheduling that will be owned by
/// the caller. We don't have a command line option to override the postRA
/// scheduler. The Target must configure it.
ScheduleDAGInstrs *PostMachineSchedulerImpl::createPostMachineScheduler() {
  // Get the postRA scheduler set by the target for this function.
  ScheduleDAGInstrs *Scheduler = TM->createPostMachineScheduler(this);
  if (Scheduler)
    return Scheduler;

  // Default to GenericScheduler.
  return createSchedPostRA(this);
}

bool PostMachineSchedulerImpl::run(MachineFunction &Func,
                                   const TargetMachine &TM,
                                   const RequiredAnalyses &Analyses) {
  MF = &Func;
  MLI = &Analyses.MLI;
  this->TM = &TM;
  AA = &Analyses.AA;

  if (VerifyScheduling) {
    const char *PostMSchedBanner = "Before post machine scheduling.";
    if (P)
      MF->verify(P, PostMSchedBanner, &errs());
    else
      MF->verify(*MFAM, PostMSchedBanner, &errs());
  }

  // Instantiate the selected scheduler for this target, function, and
  // optimization level.
  std::unique_ptr<ScheduleDAGInstrs> Scheduler(createPostMachineScheduler());
  scheduleRegions(*Scheduler, true);

  if (VerifyScheduling) {
    const char *PostMSchedBanner = "After post machine scheduling.";
    if (P)
      MF->verify(P, PostMSchedBanner, &errs());
    else
      MF->verify(*MFAM, PostMSchedBanner, &errs());
  }
  return true;
}

/// Top-level MachineScheduler pass driver.
///
/// Visit blocks in function order. Divide each block into scheduling regions
/// and visit them bottom-up. Visiting regions bottom-up is not required, but is
/// consistent with the DAG builder, which traverses the interior of the
/// scheduling regions bottom-up.
///
/// This design avoids exposing scheduling boundaries to the DAG builder,
/// simplifying the DAG builder's support for "special" target instructions.
/// At the same time the design allows target schedulers to operate across
/// scheduling boundaries, for example to bundle the boundary instructions
/// without reordering them. This creates complexity, because the target
/// scheduler must update the RegionBegin and RegionEnd positions cached by
/// ScheduleDAGInstrs whenever adding or removing instructions. A much simpler
/// design would be to split blocks at scheduling boundaries, but LLVM has a
/// general bias against block splitting purely for implementation simplicity.
bool MachineSchedulerLegacy::runOnMachineFunction(MachineFunction &MF) {
  if (skipFunction(MF.getFunction()))
    return false;

  if (EnableMachineSched.getNumOccurrences()) {
    if (!EnableMachineSched)
      return false;
  } else if (!MF.getSubtarget().enableMachineScheduler()) {
    return false;
  }

  LLVM_DEBUG(dbgs() << "Before MISched:\n"; MF.print(dbgs()));

  auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
  auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
  auto &TM = getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
  auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
  auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
  Impl.setLegacyPass(this);
  return Impl.run(MF, TM, {MLI, MDT, AA, LIS});
}

MachineSchedulerPass::MachineSchedulerPass(const TargetMachine *TM)
    : Impl(std::make_unique<MachineSchedulerImpl>()), TM(TM) {}
MachineSchedulerPass::~MachineSchedulerPass() = default;
MachineSchedulerPass::MachineSchedulerPass(MachineSchedulerPass &&Other) =
    default;

PostMachineSchedulerPass::PostMachineSchedulerPass(const TargetMachine *TM)
    : Impl(std::make_unique<PostMachineSchedulerImpl>()), TM(TM) {}
PostMachineSchedulerPass::PostMachineSchedulerPass(
    PostMachineSchedulerPass &&Other) = default;
PostMachineSchedulerPass::~PostMachineSchedulerPass() = default;

PreservedAnalyses
MachineSchedulerPass::run(MachineFunction &MF,
                          MachineFunctionAnalysisManager &MFAM) {
  if (EnableMachineSched.getNumOccurrences()) {
    if (!EnableMachineSched)
      return PreservedAnalyses::all();
  } else if (!MF.getSubtarget().enableMachineScheduler()) {
    return PreservedAnalyses::all();
  }

  LLVM_DEBUG(dbgs() << "Before MISched:\n"; MF.print(dbgs()));
  auto &MLI = MFAM.getResult<MachineLoopAnalysis>(MF);
  auto &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
  auto &FAM = MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
                  .getManager();
  auto &AA = FAM.getResult<AAManager>(MF.getFunction());
  auto &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
  Impl->setMFAM(&MFAM);
  bool Changed = Impl->run(MF, *TM, {MLI, MDT, AA, LIS});
  if (!Changed)
    return PreservedAnalyses::all();

  return getMachineFunctionPassPreservedAnalyses()
      .preserveSet<CFGAnalyses>()
      .preserve<SlotIndexesAnalysis>()
      .preserve<LiveIntervalsAnalysis>();
}

bool PostMachineSchedulerLegacy::runOnMachineFunction(MachineFunction &MF) {
  if (skipFunction(MF.getFunction()))
    return false;

  if (EnablePostRAMachineSched.getNumOccurrences()) {
    if (!EnablePostRAMachineSched)
      return false;
  } else if (!MF.getSubtarget().enablePostRAMachineScheduler()) {
    LLVM_DEBUG(dbgs() << "Subtarget disables post-MI-sched.\n");
    return false;
  }
  LLVM_DEBUG(dbgs() << "Before post-MI-sched:\n"; MF.print(dbgs()));
  auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
  auto &TM = getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
  auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
  Impl.setLegacyPass(this);
  return Impl.run(MF, TM, {MLI, AA});
}

PreservedAnalyses
PostMachineSchedulerPass::run(MachineFunction &MF,
                              MachineFunctionAnalysisManager &MFAM) {
  if (EnablePostRAMachineSched.getNumOccurrences()) {
    if (!EnablePostRAMachineSched)
      return PreservedAnalyses::all();
  } else if (!MF.getSubtarget().enablePostRAMachineScheduler()) {
    LLVM_DEBUG(dbgs() << "Subtarget disables post-MI-sched.\n");
    return PreservedAnalyses::all();
  }
  LLVM_DEBUG(dbgs() << "Before post-MI-sched:\n"; MF.print(dbgs()));
  auto &MLI = MFAM.getResult<MachineLoopAnalysis>(MF);
  auto &FAM = MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
                  .getManager();
  auto &AA = FAM.getResult<AAManager>(MF.getFunction());

  Impl->setMFAM(&MFAM);
  bool Changed = Impl->run(MF, *TM, {MLI, AA});
  if (!Changed)
    return PreservedAnalyses::all();

  PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
  PA.preserveSet<CFGAnalyses>();
  return PA;
}

/// Return true of the given instruction should not be included in a scheduling
/// region.
///
/// MachineScheduler does not currently support scheduling across calls. To
/// handle calls, the DAG builder needs to be modified to create register
/// anti/output dependencies on the registers clobbered by the call's regmask
/// operand. In PreRA scheduling, the stack pointer adjustment already prevents
/// scheduling across calls. In PostRA scheduling, we need the isCall to enforce
/// the boundary, but there would be no benefit to postRA scheduling across
/// calls this late anyway.
static bool isSchedBoundary(MachineBasicBlock::iterator MI,
                            MachineBasicBlock *MBB,
                            MachineFunction *MF,
                            const TargetInstrInfo *TII) {
  return MI->isCall() || TII->isSchedulingBoundary(*MI, MBB, *MF) ||
         MI->isFakeUse();
}

using MBBRegionsVector = SmallVector<SchedRegion, 16>;

static void
getSchedRegions(MachineBasicBlock *MBB,
                MBBRegionsVector &Regions,
                bool RegionsTopDown) {
  MachineFunction *MF = MBB->getParent();
  const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();

  MachineBasicBlock::iterator I = nullptr;
  for(MachineBasicBlock::iterator RegionEnd = MBB->end();
      RegionEnd != MBB->begin(); RegionEnd = I) {

    // Avoid decrementing RegionEnd for blocks with no terminator.
    if (RegionEnd != MBB->end() ||
        isSchedBoundary(&*std::prev(RegionEnd), &*MBB, MF, TII)) {
      --RegionEnd;
    }

    // The next region starts above the previous region. Look backward in the
    // instruction stream until we find the nearest boundary.
    unsigned NumRegionInstrs = 0;
    I = RegionEnd;
    for (;I != MBB->begin(); --I) {
      MachineInstr &MI = *std::prev(I);
      if (isSchedBoundary(&MI, &*MBB, MF, TII))
        break;
      if (!MI.isDebugOrPseudoInstr()) {
        // MBB::size() uses instr_iterator to count. Here we need a bundle to
        // count as a single instruction.
        ++NumRegionInstrs;
      }
    }

    // It's possible we found a scheduling region that only has debug
    // instructions. Don't bother scheduling these.
    if (NumRegionInstrs != 0)
      Regions.push_back(SchedRegion(I, RegionEnd, NumRegionInstrs));
  }

  if (RegionsTopDown)
    std::reverse(Regions.begin(), Regions.end());
}

/// Main driver for both MachineScheduler and PostMachineScheduler.
void MachineSchedulerBase::scheduleRegions(ScheduleDAGInstrs &Scheduler,
                                           bool FixKillFlags) {
  // Visit all machine basic blocks.
  //
  // TODO: Visit blocks in global postorder or postorder within the bottom-up
  // loop tree. Then we can optionally compute global RegPressure.
  for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end();
       MBB != MBBEnd; ++MBB) {

    Scheduler.startBlock(&*MBB);

#ifndef NDEBUG
    if (SchedOnlyFunc.getNumOccurrences() && SchedOnlyFunc != MF->getName())
      continue;
    if (SchedOnlyBlock.getNumOccurrences()
        && (int)SchedOnlyBlock != MBB->getNumber())
      continue;
#endif

    // Break the block into scheduling regions [I, RegionEnd). RegionEnd
    // points to the scheduling boundary at the bottom of the region. The DAG
    // does not include RegionEnd, but the region does (i.e. the next
    // RegionEnd is above the previous RegionBegin). If the current block has
    // no terminator then RegionEnd == MBB->end() for the bottom region.
    //
    // All the regions of MBB are first found and stored in MBBRegions, which
    // will be processed (MBB) top-down if initialized with true.
    //
    // The Scheduler may insert instructions during either schedule() or
    // exitRegion(), even for empty regions. So the local iterators 'I' and
    // 'RegionEnd' are invalid across these calls. Instructions must not be
    // added to other regions than the current one without updating MBBRegions.

    MBBRegionsVector MBBRegions;
    getSchedRegions(&*MBB, MBBRegions, Scheduler.doMBBSchedRegionsTopDown());
    bool ScheduleSingleMI = Scheduler.shouldScheduleSingleMIRegions();
    for (const SchedRegion &R : MBBRegions) {
      MachineBasicBlock::iterator I = R.RegionBegin;
      MachineBasicBlock::iterator RegionEnd = R.RegionEnd;
      unsigned NumRegionInstrs = R.NumRegionInstrs;

      // Notify the scheduler of the region, even if we may skip scheduling
      // it. Perhaps it still needs to be bundled.
      Scheduler.enterRegion(&*MBB, I, RegionEnd, NumRegionInstrs);

      // Skip empty scheduling regions and, conditionally, regions with a single
      // MI.
      if (I == RegionEnd || (!ScheduleSingleMI && I == std::prev(RegionEnd))) {
        // Close the current region. Bundle the terminator if needed.
        // This invalidates 'RegionEnd' and 'I'.
        Scheduler.exitRegion();
        continue;
      }
      LLVM_DEBUG(dbgs() << "********** MI Scheduling **********\n");
      LLVM_DEBUG(dbgs() << MF->getName() << ":" << printMBBReference(*MBB)
                        << " " << MBB->getName() << "\n  From: " << *I
                        << "    To: ";
                 if (RegionEnd != MBB->end()) dbgs() << *RegionEnd;
                 else dbgs() << "End\n";
                 dbgs() << " RegionInstrs: " << NumRegionInstrs << '\n');
      if (DumpCriticalPathLength) {
        errs() << MF->getName();
        errs() << ":%bb. " << MBB->getNumber();
        errs() << " " << MBB->getName() << " \n";
      }

      // Schedule a region: possibly reorder instructions.
      // This invalidates the original region iterators.
      Scheduler.schedule();

      // Close the current region.
      Scheduler.exitRegion();
    }
    Scheduler.finishBlock();
    // FIXME: Ideally, no further passes should rely on kill flags. However,
    // thumb2 size reduction is currently an exception, so the PostMIScheduler
    // needs to do this.
    if (FixKillFlags)
      Scheduler.fixupKills(*MBB);
  }
  Scheduler.finalizeSchedule();
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void ReadyQueue::dump() const {
  dbgs() << "Queue " << Name << ": ";
  for (const SUnit *SU : Queue)
    dbgs() << SU->NodeNum << " ";
  dbgs() << "\n";
}
#endif

//===----------------------------------------------------------------------===//
// ScheduleDAGMI - Basic machine instruction scheduling. This is
// independent of PreRA/PostRA scheduling and involves no extra book-keeping for
// virtual registers.
// ===----------------------------------------------------------------------===/

// Provide a vtable anchor.
ScheduleDAGMI::~ScheduleDAGMI() = default;

/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. When
/// NumPredsLeft reaches zero, release the successor node.
///
/// FIXME: Adjust SuccSU height based on MinLatency.
void ScheduleDAGMI::releaseSucc(SUnit *SU, SDep *SuccEdge) {
  SUnit *SuccSU = SuccEdge->getSUnit();

  if (SuccEdge->isWeak()) {
    --SuccSU->WeakPredsLeft;
    return;
  }
#ifndef NDEBUG
  if (SuccSU->NumPredsLeft == 0) {
    dbgs() << "*** Scheduling failed! ***\n";
    dumpNode(*SuccSU);
    dbgs() << " has been released too many times!\n";
    llvm_unreachable(nullptr);
  }
#endif
  // SU->TopReadyCycle was set to CurrCycle when it was scheduled. However,
  // CurrCycle may have advanced since then.
  if (SuccSU->TopReadyCycle < SU->TopReadyCycle + SuccEdge->getLatency())
    SuccSU->TopReadyCycle = SU->TopReadyCycle + SuccEdge->getLatency();

  --SuccSU->NumPredsLeft;
  if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU)
    SchedImpl->releaseTopNode(SuccSU);
}

/// releaseSuccessors - Call releaseSucc on each of SU's successors.
void ScheduleDAGMI::releaseSuccessors(SUnit *SU) {
  for (SDep &Succ : SU->Succs)
    releaseSucc(SU, &Succ);
}

/// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. When
/// NumSuccsLeft reaches zero, release the predecessor node.
///
/// FIXME: Adjust PredSU height based on MinLatency.
void ScheduleDAGMI::releasePred(SUnit *SU, SDep *PredEdge) {
  SUnit *PredSU = PredEdge->getSUnit();

  if (PredEdge->isWeak()) {
    --PredSU->WeakSuccsLeft;
    return;
  }
#ifndef NDEBUG
  if (PredSU->NumSuccsLeft == 0) {
    dbgs() << "*** Scheduling failed! ***\n";
    dumpNode(*PredSU);
    dbgs() << " has been released too many times!\n";
    llvm_unreachable(nullptr);
  }
#endif
  // SU->BotReadyCycle was set to CurrCycle when it was scheduled. However,
  // CurrCycle may have advanced since then.
  if (PredSU->BotReadyCycle < SU->BotReadyCycle + PredEdge->getLatency())
    PredSU->BotReadyCycle = SU->BotReadyCycle + PredEdge->getLatency();

  --PredSU->NumSuccsLeft;
  if (PredSU->NumSuccsLeft == 0 && PredSU != &EntrySU)
    SchedImpl->releaseBottomNode(PredSU);
}

/// releasePredecessors - Call releasePred on each of SU's predecessors.
void ScheduleDAGMI::releasePredecessors(SUnit *SU) {
  for (SDep &Pred : SU->Preds)
    releasePred(SU, &Pred);
}

void ScheduleDAGMI::startBlock(MachineBasicBlock *bb) {
  ScheduleDAGInstrs::startBlock(bb);
  SchedImpl->enterMBB(bb);
}

void ScheduleDAGMI::finishBlock() {
  SchedImpl->leaveMBB();
  ScheduleDAGInstrs::finishBlock();
}

/// enterRegion - Called back from PostMachineScheduler::runOnMachineFunction
/// after crossing a scheduling boundary. [begin, end) includes all instructions
/// in the region, including the boundary itself and single-instruction regions
/// that don't get scheduled.
void ScheduleDAGMI::enterRegion(MachineBasicBlock *bb,
                                     MachineBasicBlock::iterator begin,
                                     MachineBasicBlock::iterator end,
                                     unsigned regioninstrs)
{
  ScheduleDAGInstrs::enterRegion(bb, begin, end, regioninstrs);

  SchedImpl->initPolicy(begin, end, regioninstrs);

  // Set dump direction after initializing sched policy.
  ScheduleDAGMI::DumpDirection D;
  if (SchedImpl->getPolicy().OnlyTopDown)
    D = ScheduleDAGMI::DumpDirection::TopDown;
  else if (SchedImpl->getPolicy().OnlyBottomUp)
    D = ScheduleDAGMI::DumpDirection::BottomUp;
  else
    D = ScheduleDAGMI::DumpDirection::Bidirectional;
  setDumpDirection(D);
}

/// This is normally called from the main scheduler loop but may also be invoked
/// by the scheduling strategy to perform additional code motion.
void ScheduleDAGMI::moveInstruction(
  MachineInstr *MI, MachineBasicBlock::iterator InsertPos) {
  // Advance RegionBegin if the first instruction moves down.
  if (&*RegionBegin == MI)
    ++RegionBegin;

  // Update the instruction stream.
  BB->splice(InsertPos, BB, MI);

  // Update LiveIntervals
  if (LIS)
    LIS->handleMove(*MI, /*UpdateFlags=*/true);

  // Recede RegionBegin if an instruction moves above the first.
  if (RegionBegin == InsertPos)
    RegionBegin = MI;
}

bool ScheduleDAGMI::checkSchedLimit() {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS && !defined(NDEBUG)
  if (NumInstrsScheduled == MISchedCutoff && MISchedCutoff != ~0U) {
    CurrentTop = CurrentBottom;
    return false;
  }
  ++NumInstrsScheduled;
#endif
  return true;
}

/// Per-region scheduling driver, called back from
/// PostMachineScheduler::runOnMachineFunction. This is a simplified driver
/// that does not consider liveness or register pressure. It is useful for
/// PostRA scheduling and potentially other custom schedulers.
void ScheduleDAGMI::schedule() {
  LLVM_DEBUG(dbgs() << "ScheduleDAGMI::schedule starting\n");
  LLVM_DEBUG(SchedImpl->dumpPolicy());

  // Build the DAG.
  buildSchedGraph(AA);

  postProcessDAG();

  SmallVector<SUnit*, 8> TopRoots, BotRoots;
  findRootsAndBiasEdges(TopRoots, BotRoots);

  LLVM_DEBUG(dump());
  if (PrintDAGs) dump();
  if (ViewMISchedDAGs) viewGraph();

  // Initialize the strategy before modifying the DAG.
  // This may initialize a DFSResult to be used for queue priority.
  SchedImpl->initialize(this);

  // Initialize ready queues now that the DAG and priority data are finalized.
  initQueues(TopRoots, BotRoots);

  bool IsTopNode = false;
  while (true) {
    if (!checkSchedLimit())
      break;

    LLVM_DEBUG(dbgs() << "** ScheduleDAGMI::schedule picking next node\n");
    SUnit *SU = SchedImpl->pickNode(IsTopNode);
    if (!SU) break;

    assert(!SU->isScheduled && "Node already scheduled");

    MachineInstr *MI = SU->getInstr();
    if (IsTopNode) {
      assert(SU->isTopReady() && "node still has unscheduled dependencies");
      if (&*CurrentTop == MI)
        CurrentTop = nextIfDebug(++CurrentTop, CurrentBottom);
      else
        moveInstruction(MI, CurrentTop);
    } else {
      assert(SU->isBottomReady() && "node still has unscheduled dependencies");
      MachineBasicBlock::iterator priorII =
        priorNonDebug(CurrentBottom, CurrentTop);
      if (&*priorII == MI)
        CurrentBottom = priorII;
      else {
        if (&*CurrentTop == MI)
          CurrentTop = nextIfDebug(++CurrentTop, priorII);
        moveInstruction(MI, CurrentBottom);
        CurrentBottom = MI;
      }
    }
    // Notify the scheduling strategy before updating the DAG.
    // This sets the scheduled node's ReadyCycle to CurrCycle. When updateQueues
    // runs, it can then use the accurate ReadyCycle time to determine whether
    // newly released nodes can move to the readyQ.
    SchedImpl->schedNode(SU, IsTopNode);

    updateQueues(SU, IsTopNode);
  }
  assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone.");

  placeDebugValues();

  LLVM_DEBUG({
    dbgs() << "*** Final schedule for "
           << printMBBReference(*begin()->getParent()) << " ***\n";
    dumpSchedule();
    dbgs() << '\n';
  });
}

/// Apply each ScheduleDAGMutation step in order.
void ScheduleDAGMI::postProcessDAG() {
  for (auto &m : Mutations)
    m->apply(this);
}

void ScheduleDAGMI::
findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots,
                      SmallVectorImpl<SUnit*> &BotRoots) {
  for (SUnit &SU : SUnits) {
    assert(!SU.isBoundaryNode() && "Boundary node should not be in SUnits");

    // Order predecessors so DFSResult follows the critical path.
    SU.biasCriticalPath();

    // A SUnit is ready to top schedule if it has no predecessors.
    if (!SU.NumPredsLeft)
      TopRoots.push_back(&SU);
    // A SUnit is ready to bottom schedule if it has no successors.
    if (!SU.NumSuccsLeft)
      BotRoots.push_back(&SU);
  }
  ExitSU.biasCriticalPath();
}

/// Identify DAG roots and setup scheduler queues.
void ScheduleDAGMI::initQueues(ArrayRef<SUnit *> TopRoots,
                               ArrayRef<SUnit *> BotRoots) {
  // Release all DAG roots for scheduling, not including EntrySU/ExitSU.
  //
  // Nodes with unreleased weak edges can still be roots.
  // Release top roots in forward order.
  for (SUnit *SU : TopRoots)
    SchedImpl->releaseTopNode(SU);

  // Release bottom roots in reverse order so the higher priority nodes appear
  // first. This is more natural and slightly more efficient.
  for (SmallVectorImpl<SUnit*>::const_reverse_iterator
         I = BotRoots.rbegin(), E = BotRoots.rend(); I != E; ++I) {
    SchedImpl->releaseBottomNode(*I);
  }

  releaseSuccessors(&EntrySU);
  releasePredecessors(&ExitSU);

  SchedImpl->registerRoots();

  // Advance past initial DebugValues.
  CurrentTop = nextIfDebug(RegionBegin, RegionEnd);
  CurrentBottom = RegionEnd;
}

/// Update scheduler queues after scheduling an instruction.
void ScheduleDAGMI::updateQueues(SUnit *SU, bool IsTopNode) {
  // Release dependent instructions for scheduling.
  if (IsTopNode)
    releaseSuccessors(SU);
  else
    releasePredecessors(SU);

  SU->isScheduled = true;
}

/// Reinsert any remaining debug_values, just like the PostRA scheduler.
void ScheduleDAGMI::placeDebugValues() {
  // If first instruction was a DBG_VALUE then put it back.
  if (FirstDbgValue) {
    BB->splice(RegionBegin, BB, FirstDbgValue);
    RegionBegin = FirstDbgValue;
  }

  for (std::vector<std::pair<MachineInstr *, MachineInstr *>>::iterator
         DI = DbgValues.end(), DE = DbgValues.begin(); DI != DE; --DI) {
    std::pair<MachineInstr *, MachineInstr *> P = *std::prev(DI);
    MachineInstr *DbgValue = P.first;
    MachineBasicBlock::iterator OrigPrevMI = P.second;
    if (&*RegionBegin == DbgValue)
      ++RegionBegin;
    BB->splice(std::next(OrigPrevMI), BB, DbgValue);
    if (RegionEnd != BB->end() && OrigPrevMI == &*RegionEnd)
      RegionEnd = DbgValue;
  }
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
static const char *scheduleTableLegend = "  i: issue\n  x: resource booked";

LLVM_DUMP_METHOD void ScheduleDAGMI::dumpScheduleTraceTopDown() const {
  // Bail off when there is no schedule model to query.
  if (!SchedModel.hasInstrSchedModel())
    return;

  //  Nothing to show if there is no or just one instruction.
  if (BB->size() < 2)
    return;

  dbgs() << " * Schedule table (TopDown):\n";
  dbgs() << scheduleTableLegend << "\n";
  const unsigned FirstCycle = getSUnit(&*(std::begin(*this)))->TopReadyCycle;
  unsigned LastCycle = getSUnit(&*(std::prev(std::end(*this))))->TopReadyCycle;
  for (MachineInstr &MI : *this) {
    SUnit *SU = getSUnit(&MI);
    if (!SU)
      continue;
    const MCSchedClassDesc *SC = getSchedClass(SU);
    for (TargetSchedModel::ProcResIter PI = SchedModel.getWriteProcResBegin(SC),
                                       PE = SchedModel.getWriteProcResEnd(SC);
         PI != PE; ++PI) {
      if (SU->TopReadyCycle + PI->ReleaseAtCycle - 1 > LastCycle)
        LastCycle = SU->TopReadyCycle + PI->ReleaseAtCycle - 1;
    }
  }
  // Print the header with the cycles
  dbgs() << llvm::left_justify("Cycle", HeaderColWidth);
  for (unsigned C = FirstCycle; C <= LastCycle; ++C)
    dbgs() << llvm::left_justify("| " + std::to_string(C), ColWidth);
  dbgs() << "|\n";

  for (MachineInstr &MI : *this) {
    SUnit *SU = getSUnit(&MI);
    if (!SU) {
      dbgs() << "Missing SUnit\n";
      continue;
    }
    std::string NodeName("SU(");
    NodeName += std::to_string(SU->NodeNum) + ")";
    dbgs() << llvm::left_justify(NodeName, HeaderColWidth);
    unsigned C = FirstCycle;
    for (; C <= LastCycle; ++C) {
      if (C == SU->TopReadyCycle)
        dbgs() << llvm::left_justify("| i", ColWidth);
      else
        dbgs() << llvm::left_justify("|", ColWidth);
    }
    dbgs() << "|\n";
    const MCSchedClassDesc *SC = getSchedClass(SU);

    SmallVector<MCWriteProcResEntry, 4> ResourcesIt(
        make_range(SchedModel.getWriteProcResBegin(SC),
                   SchedModel.getWriteProcResEnd(SC)));

    if (MISchedSortResourcesInTrace)
      llvm::stable_sort(
          ResourcesIt,
          [](const MCWriteProcResEntry &LHS,
             const MCWriteProcResEntry &RHS) -> bool {
            return std::tie(LHS.AcquireAtCycle, LHS.ReleaseAtCycle) <
                   std::tie(RHS.AcquireAtCycle, RHS.ReleaseAtCycle);
          });
    for (const MCWriteProcResEntry &PI : ResourcesIt) {
      C = FirstCycle;
      const std::string ResName =
          SchedModel.getResourceName(PI.ProcResourceIdx);
      dbgs() << llvm::right_justify(ResName + " ", HeaderColWidth);
      for (; C < SU->TopReadyCycle + PI.AcquireAtCycle; ++C) {
        dbgs() << llvm::left_justify("|", ColWidth);
      }
      for (unsigned I = 0, E = PI.ReleaseAtCycle - PI.AcquireAtCycle; I != E;
           ++I, ++C)
        dbgs() << llvm::left_justify("| x", ColWidth);
      while (C++ <= LastCycle)
        dbgs() << llvm::left_justify("|", ColWidth);
      // Place end char
      dbgs() << "| \n";
    }
  }
}

LLVM_DUMP_METHOD void ScheduleDAGMI::dumpScheduleTraceBottomUp() const {
  // Bail off when there is no schedule model to query.
  if (!SchedModel.hasInstrSchedModel())
    return;

  //  Nothing to show if there is no or just one instruction.
  if (BB->size() < 2)
    return;

  dbgs() << " * Schedule table (BottomUp):\n";
  dbgs() << scheduleTableLegend << "\n";

  const int FirstCycle = getSUnit(&*(std::begin(*this)))->BotReadyCycle;
  int LastCycle = getSUnit(&*(std::prev(std::end(*this))))->BotReadyCycle;
  for (MachineInstr &MI : *this) {
    SUnit *SU = getSUnit(&MI);
    if (!SU)
      continue;
    const MCSchedClassDesc *SC = getSchedClass(SU);
    for (TargetSchedModel::ProcResIter PI = SchedModel.getWriteProcResBegin(SC),
                                       PE = SchedModel.getWriteProcResEnd(SC);
         PI != PE; ++PI) {
      if ((int)SU->BotReadyCycle - PI->ReleaseAtCycle + 1 < LastCycle)
        LastCycle = (int)SU->BotReadyCycle - PI->ReleaseAtCycle + 1;
    }
  }
  // Print the header with the cycles
  dbgs() << llvm::left_justify("Cycle", HeaderColWidth);
  for (int C = FirstCycle; C >= LastCycle; --C)
    dbgs() << llvm::left_justify("| " + std::to_string(C), ColWidth);
  dbgs() << "|\n";

  for (MachineInstr &MI : *this) {
    SUnit *SU = getSUnit(&MI);
    if (!SU) {
      dbgs() << "Missing SUnit\n";
      continue;
    }
    std::string NodeName("SU(");
    NodeName += std::to_string(SU->NodeNum) + ")";
    dbgs() << llvm::left_justify(NodeName, HeaderColWidth);
    int C = FirstCycle;
    for (; C >= LastCycle; --C) {
      if (C == (int)SU->BotReadyCycle)
        dbgs() << llvm::left_justify("| i", ColWidth);
      else
        dbgs() << llvm::left_justify("|", ColWidth);
    }
    dbgs() << "|\n";
    const MCSchedClassDesc *SC = getSchedClass(SU);
    SmallVector<MCWriteProcResEntry, 4> ResourcesIt(
        make_range(SchedModel.getWriteProcResBegin(SC),
                   SchedModel.getWriteProcResEnd(SC)));

    if (MISchedSortResourcesInTrace)
      llvm::stable_sort(
          ResourcesIt,
          [](const MCWriteProcResEntry &LHS,
             const MCWriteProcResEntry &RHS) -> bool {
            return std::tie(LHS.AcquireAtCycle, LHS.ReleaseAtCycle) <
                   std::tie(RHS.AcquireAtCycle, RHS.ReleaseAtCycle);
          });
    for (const MCWriteProcResEntry &PI : ResourcesIt) {
      C = FirstCycle;
      const std::string ResName =
          SchedModel.getResourceName(PI.ProcResourceIdx);
      dbgs() << llvm::right_justify(ResName + " ", HeaderColWidth);
      for (; C > ((int)SU->BotReadyCycle - (int)PI.AcquireAtCycle); --C) {
        dbgs() << llvm::left_justify("|", ColWidth);
      }
      for (unsigned I = 0, E = PI.ReleaseAtCycle - PI.AcquireAtCycle; I != E;
           ++I, --C)
        dbgs() << llvm::left_justify("| x", ColWidth);
      while (C-- >= LastCycle)
        dbgs() << llvm::left_justify("|", ColWidth);
      // Place end char
      dbgs() << "| \n";
    }
  }
}
#endif

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void ScheduleDAGMI::dumpSchedule() const {
  if (MISchedDumpScheduleTrace) {
    if (DumpDir == DumpDirection::TopDown)
      dumpScheduleTraceTopDown();
    else if (DumpDir == DumpDirection::BottomUp)
      dumpScheduleTraceBottomUp();
    else if (DumpDir == DumpDirection::Bidirectional) {
      dbgs() << "* Schedule table (Bidirectional): not implemented\n";
    } else {
      dbgs() << "* Schedule table: DumpDirection not set.\n";
    }
  }

  for (MachineInstr &MI : *this) {
    if (SUnit *SU = getSUnit(&MI))
      dumpNode(*SU);
    else
      dbgs() << "Missing SUnit\n";
  }
}
#endif

//===----------------------------------------------------------------------===//
// ScheduleDAGMILive - Base class for MachineInstr scheduling with LiveIntervals
// preservation.
//===----------------------------------------------------------------------===//

ScheduleDAGMILive::~ScheduleDAGMILive() {
  delete DFSResult;
}

void ScheduleDAGMILive::collectVRegUses(SUnit &SU) {
  const MachineInstr &MI = *SU.getInstr();
  for (const MachineOperand &MO : MI.operands()) {
    if (!MO.isReg())
      continue;
    if (!MO.readsReg())
      continue;
    if (TrackLaneMasks && !MO.isUse())
      continue;

    Register Reg = MO.getReg();
    if (!Reg.isVirtual())
      continue;

    // Ignore re-defs.
    if (TrackLaneMasks) {
      bool FoundDef = false;
      for (const MachineOperand &MO2 : MI.all_defs()) {
        if (MO2.getReg() == Reg && !MO2.isDead()) {
          FoundDef = true;
          break;
        }
      }
      if (FoundDef)
        continue;
    }

    // Record this local VReg use.
    VReg2SUnitMultiMap::iterator UI = VRegUses.find(Reg);
    for (; UI != VRegUses.end(); ++UI) {
      if (UI->SU == &SU)
        break;
    }
    if (UI == VRegUses.end())
      VRegUses.insert(VReg2SUnit(Reg, LaneBitmask::getNone(), &SU));
  }
}

/// enterRegion - Called back from MachineScheduler::runOnMachineFunction after
/// crossing a scheduling boundary. [begin, end) includes all instructions in
/// the region, including the boundary itself and single-instruction regions
/// that don't get scheduled.
void ScheduleDAGMILive::enterRegion(MachineBasicBlock *bb,
                                MachineBasicBlock::iterator begin,
                                MachineBasicBlock::iterator end,
                                unsigned regioninstrs)
{
  // ScheduleDAGMI initializes SchedImpl's per-region policy.
  ScheduleDAGMI::enterRegion(bb, begin, end, regioninstrs);

  // For convenience remember the end of the liveness region.
  LiveRegionEnd = (RegionEnd == bb->end()) ? RegionEnd : std::next(RegionEnd);

  SUPressureDiffs.clear();

  ShouldTrackPressure = SchedImpl->shouldTrackPressure();
  ShouldTrackLaneMasks = SchedImpl->shouldTrackLaneMasks();

  assert((!ShouldTrackLaneMasks || ShouldTrackPressure) &&
         "ShouldTrackLaneMasks requires ShouldTrackPressure");
}

// Setup the register pressure trackers for the top scheduled and bottom
// scheduled regions.
void ScheduleDAGMILive::initRegPressure() {
  VRegUses.clear();
  VRegUses.setUniverse(MRI.getNumVirtRegs());
  for (SUnit &SU : SUnits)
    collectVRegUses(SU);

  TopRPTracker.init(&MF, RegClassInfo, LIS, BB, RegionBegin,
                    ShouldTrackLaneMasks, false);
  BotRPTracker.init(&MF, RegClassInfo, LIS, BB, LiveRegionEnd,
                    ShouldTrackLaneMasks, false);

  // Close the RPTracker to finalize live ins.
  RPTracker.closeRegion();

  LLVM_DEBUG(RPTracker.dump());

  // Initialize the live ins and live outs.
  TopRPTracker.addLiveRegs(RPTracker.getPressure().LiveInRegs);
  BotRPTracker.addLiveRegs(RPTracker.getPressure().LiveOutRegs);

  // Close one end of the tracker so we can call
  // getMaxUpward/DownwardPressureDelta before advancing across any
  // instructions. This converts currently live regs into live ins/outs.
  TopRPTracker.closeTop();
  BotRPTracker.closeBottom();

  BotRPTracker.initLiveThru(RPTracker);
  if (!BotRPTracker.getLiveThru().empty()) {
    TopRPTracker.initLiveThru(BotRPTracker.getLiveThru());
    LLVM_DEBUG(dbgs() << "Live Thru: ";
               dumpRegSetPressure(BotRPTracker.getLiveThru(), TRI));
  };

  // For each live out vreg reduce the pressure change associated with other
  // uses of the same vreg below the live-out reaching def.
  updatePressureDiffs(RPTracker.getPressure().LiveOutRegs);

  // Account for liveness generated by the region boundary.
  if (LiveRegionEnd != RegionEnd) {
    SmallVector<VRegMaskOrUnit, 8> LiveUses;
    BotRPTracker.recede(&LiveUses);
    updatePressureDiffs(LiveUses);
  }

  LLVM_DEBUG(dbgs() << "Top Pressure: ";
             dumpRegSetPressure(TopRPTracker.getRegSetPressureAtPos(), TRI);
             dbgs() << "Bottom Pressure: ";
             dumpRegSetPressure(BotRPTracker.getRegSetPressureAtPos(), TRI););

  assert((BotRPTracker.getPos() == RegionEnd ||
          (RegionEnd->isDebugInstr() &&
           BotRPTracker.getPos() == priorNonDebug(RegionEnd, RegionBegin))) &&
         "Can't find the region bottom");

  // Cache the list of excess pressure sets in this region. This will also track
  // the max pressure in the scheduled code for these sets.
  RegionCriticalPSets.clear();
  const std::vector<unsigned> &RegionPressure =
    RPTracker.getPressure().MaxSetPressure;
  for (unsigned i = 0, e = RegionPressure.size(); i < e; ++i) {
    unsigned Limit = RegClassInfo->getRegPressureSetLimit(i);
    if (RegionPressure[i] > Limit) {
      LLVM_DEBUG(dbgs() << TRI->getRegPressureSetName(i) << " Limit " << Limit
                        << " Actual " << RegionPressure[i] << "\n");
      RegionCriticalPSets.push_back(PressureChange(i));
    }
  }
  LLVM_DEBUG({
    if (RegionCriticalPSets.size() > 0) {
      dbgs() << "Excess PSets: ";
      for (const PressureChange &RCPS : RegionCriticalPSets)
        dbgs() << TRI->getRegPressureSetName(RCPS.getPSet()) << " ";
      dbgs() << "\n";
    }
  });
}

void ScheduleDAGMILive::
updateScheduledPressure(const SUnit *SU,
                        const std::vector<unsigned> &NewMaxPressure) {
  const PressureDiff &PDiff = getPressureDiff(SU);
  unsigned CritIdx = 0, CritEnd = RegionCriticalPSets.size();
  for (const PressureChange &PC : PDiff) {
    if (!PC.isValid())
      break;
    unsigned ID = PC.getPSet();
    while (CritIdx != CritEnd && RegionCriticalPSets[CritIdx].getPSet() < ID)
      ++CritIdx;
    if (CritIdx != CritEnd && RegionCriticalPSets[CritIdx].getPSet() == ID) {
      if ((int)NewMaxPressure[ID] > RegionCriticalPSets[CritIdx].getUnitInc()
          && NewMaxPressure[ID] <= (unsigned)std::numeric_limits<int16_t>::max())
        RegionCriticalPSets[CritIdx].setUnitInc(NewMaxPressure[ID]);
    }
    unsigned Limit = RegClassInfo->getRegPressureSetLimit(ID);
    if (NewMaxPressure[ID] >= Limit - 2) {
      LLVM_DEBUG(dbgs() << "  " << TRI->getRegPressureSetName(ID) << ": "
                        << NewMaxPressure[ID]
                        << ((NewMaxPressure[ID] > Limit) ? " > " : " <= ")
                        << Limit << "(+ " << BotRPTracker.getLiveThru()[ID]
                        << " livethru)\n");
    }
  }
}

/// Update the PressureDiff array for liveness after scheduling this
/// instruction.
void ScheduleDAGMILive::updatePressureDiffs(ArrayRef<VRegMaskOrUnit> LiveUses) {
  for (const VRegMaskOrUnit &P : LiveUses) {
    Register Reg = P.RegUnit;
    /// FIXME: Currently assuming single-use physregs.
    if (!Reg.isVirtual())
      continue;

    if (ShouldTrackLaneMasks) {
      // If the register has just become live then other uses won't change
      // this fact anymore => decrement pressure.
      // If the register has just become dead then other uses make it come
      // back to life => increment pressure.
      bool Decrement = P.LaneMask.any();

      for (const VReg2SUnit &V2SU
           : make_range(VRegUses.find(Reg), VRegUses.end())) {
        SUnit &SU = *V2SU.SU;
        if (SU.isScheduled || &SU == &ExitSU)
          continue;

        PressureDiff &PDiff = getPressureDiff(&SU);
        PDiff.addPressureChange(Reg, Decrement, &MRI);
        if (llvm::any_of(PDiff, [](const PressureChange &Change) {
              return Change.isValid();
            }))
          LLVM_DEBUG(dbgs()
                         << "  UpdateRegPressure: SU(" << SU.NodeNum << ") "
                         << printReg(Reg, TRI) << ':'
                         << PrintLaneMask(P.LaneMask) << ' ' << *SU.getInstr();
                     dbgs() << "                     to "; PDiff.dump(*TRI););
      }
    } else {
      assert(P.LaneMask.any());
      LLVM_DEBUG(dbgs() << "  LiveReg: " << printVRegOrUnit(Reg, TRI) << "\n");
      // This may be called before CurrentBottom has been initialized. However,
      // BotRPTracker must have a valid position. We want the value live into the
      // instruction or live out of the block, so ask for the previous
      // instruction's live-out.
      const LiveInterval &LI = LIS->getInterval(Reg);
      VNInfo *VNI;
      MachineBasicBlock::const_iterator I =
        nextIfDebug(BotRPTracker.getPos(), BB->end());
      if (I == BB->end())
        VNI = LI.getVNInfoBefore(LIS->getMBBEndIdx(BB));
      else {
        LiveQueryResult LRQ = LI.Query(LIS->getInstructionIndex(*I));
        VNI = LRQ.valueIn();
      }
      // RegisterPressureTracker guarantees that readsReg is true for LiveUses.
      assert(VNI && "No live value at use.");
      for (const VReg2SUnit &V2SU
           : make_range(VRegUses.find(Reg), VRegUses.end())) {
        SUnit *SU = V2SU.SU;
        // If this use comes before the reaching def, it cannot be a last use,
        // so decrease its pressure change.
        if (!SU->isScheduled && SU != &ExitSU) {
          LiveQueryResult LRQ =
              LI.Query(LIS->getInstructionIndex(*SU->getInstr()));
          if (LRQ.valueIn() == VNI) {
            PressureDiff &PDiff = getPressureDiff(SU);
            PDiff.addPressureChange(Reg, true, &MRI);
            if (llvm::any_of(PDiff, [](const PressureChange &Change) {
                  return Change.isValid();
                }))
              LLVM_DEBUG(dbgs() << "  UpdateRegPressure: SU(" << SU->NodeNum
                                << ") " << *SU->getInstr();
                         dbgs() << "                     to ";
                         PDiff.dump(*TRI););
          }
        }
      }
    }
  }
}

void ScheduleDAGMILive::dump() const {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  if (EntrySU.getInstr() != nullptr)
    dumpNodeAll(EntrySU);
  for (const SUnit &SU : SUnits) {
    dumpNodeAll(SU);
    if (ShouldTrackPressure) {
      dbgs() << "  Pressure Diff      : ";
      getPressureDiff(&SU).dump(*TRI);
    }
    dbgs() << "  Single Issue       : ";
    if (SchedModel.mustBeginGroup(SU.getInstr()) &&
        SchedModel.mustEndGroup(SU.getInstr()))
      dbgs() << "true;";
    else
      dbgs() << "false;";
    dbgs() << '\n';
  }
  if (ExitSU.getInstr() != nullptr)
    dumpNodeAll(ExitSU);
#endif
}

/// schedule - Called back from MachineScheduler::runOnMachineFunction
/// after setting up the current scheduling region. [RegionBegin, RegionEnd)
/// only includes instructions that have DAG nodes, not scheduling boundaries.
///
/// This is a skeletal driver, with all the functionality pushed into helpers,
/// so that it can be easily extended by experimental schedulers. Generally,
/// implementing MachineSchedStrategy should be sufficient to implement a new
/// scheduling algorithm. However, if a scheduler further subclasses
/// ScheduleDAGMILive then it will want to override this virtual method in order
/// to update any specialized state.
void ScheduleDAGMILive::schedule() {
  LLVM_DEBUG(dbgs() << "ScheduleDAGMILive::schedule starting\n");
  LLVM_DEBUG(SchedImpl->dumpPolicy());
  buildDAGWithRegPressure();

  postProcessDAG();

  SmallVector<SUnit*, 8> TopRoots, BotRoots;
  findRootsAndBiasEdges(TopRoots, BotRoots);

  // Initialize the strategy before modifying the DAG.
  // This may initialize a DFSResult to be used for queue priority.
  SchedImpl->initialize(this);

  LLVM_DEBUG(dump());
  if (PrintDAGs) dump();
  if (ViewMISchedDAGs) viewGraph();

  // Initialize ready queues now that the DAG and priority data are finalized.
  initQueues(TopRoots, BotRoots);

  bool IsTopNode = false;
  while (true) {
    if (!checkSchedLimit())
      break;

    LLVM_DEBUG(dbgs() << "** ScheduleDAGMILive::schedule picking next node\n");
    SUnit *SU = SchedImpl->pickNode(IsTopNode);
    if (!SU) break;

    assert(!SU->isScheduled && "Node already scheduled");

    scheduleMI(SU, IsTopNode);

    if (DFSResult) {
      unsigned SubtreeID = DFSResult->getSubtreeID(SU);
      if (!ScheduledTrees.test(SubtreeID)) {
        ScheduledTrees.set(SubtreeID);
        DFSResult->scheduleTree(SubtreeID);
        SchedImpl->scheduleTree(SubtreeID);
      }
    }

    // Notify the scheduling strategy after updating the DAG.
    SchedImpl->schedNode(SU, IsTopNode);

    updateQueues(SU, IsTopNode);
  }
  assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone.");

  placeDebugValues();

  LLVM_DEBUG({
    dbgs() << "*** Final schedule for "
           << printMBBReference(*begin()->getParent()) << " ***\n";
    dumpSchedule();
    dbgs() << '\n';
  });
}

/// Build the DAG and setup three register pressure trackers.
void ScheduleDAGMILive::buildDAGWithRegPressure() {
  if (!ShouldTrackPressure) {
    RPTracker.reset();
    RegionCriticalPSets.clear();
    buildSchedGraph(AA);
    return;
  }

  // Initialize the register pressure tracker used by buildSchedGraph.
  RPTracker.init(&MF, RegClassInfo, LIS, BB, LiveRegionEnd,
                 ShouldTrackLaneMasks, /*TrackUntiedDefs=*/true);

  // Account for liveness generate by the region boundary.
  if (LiveRegionEnd != RegionEnd)
    RPTracker.recede();

  // Build the DAG, and compute current register pressure.
  buildSchedGraph(AA, &RPTracker, &SUPressureDiffs, LIS, ShouldTrackLaneMasks);

  // Initialize top/bottom trackers after computing region pressure.
  initRegPressure();
}

void ScheduleDAGMILive::computeDFSResult() {
  if (!DFSResult)
    DFSResult = new SchedDFSResult(/*BottomU*/true, MinSubtreeSize);
  DFSResult->clear();
  ScheduledTrees.clear();
  DFSResult->resize(SUnits.size());
  DFSResult->compute(SUnits);
  ScheduledTrees.resize(DFSResult->getNumSubtrees());
}

/// Compute the max cyclic critical path through the DAG. The scheduling DAG
/// only provides the critical path for single block loops. To handle loops that
/// span blocks, we could use the vreg path latencies provided by
/// MachineTraceMetrics instead. However, MachineTraceMetrics is not currently
/// available for use in the scheduler.
///
/// The cyclic path estimation identifies a def-use pair that crosses the back
/// edge and considers the depth and height of the nodes. For example, consider
/// the following instruction sequence where each instruction has unit latency
/// and defines an eponymous virtual register:
///
/// a->b(a,c)->c(b)->d(c)->exit
///
/// The cyclic critical path is a two cycles: b->c->b
/// The acyclic critical path is four cycles: a->b->c->d->exit
/// LiveOutHeight = height(c) = len(c->d->exit) = 2
/// LiveOutDepth = depth(c) + 1 = len(a->b->c) + 1 = 3
/// LiveInHeight = height(b) + 1 = len(b->c->d->exit) + 1 = 4
/// LiveInDepth = depth(b) = len(a->b) = 1
///
/// LiveOutDepth - LiveInDepth = 3 - 1 = 2
/// LiveInHeight - LiveOutHeight = 4 - 2 = 2
/// CyclicCriticalPath = min(2, 2) = 2
///
/// This could be relevant to PostRA scheduling, but is currently implemented
/// assuming LiveIntervals.
unsigned ScheduleDAGMILive::computeCyclicCriticalPath() {
  // This only applies to single block loop.
  if (!BB->isSuccessor(BB))
    return 0;

  unsigned MaxCyclicLatency = 0;
  // Visit each live out vreg def to find def/use pairs that cross iterations.
  for (const VRegMaskOrUnit &P : RPTracker.getPressure().LiveOutRegs) {
    Register Reg = P.RegUnit;
    if (!Reg.isVirtual())
      continue;
    const LiveInterval &LI = LIS->getInterval(Reg);
    const VNInfo *DefVNI = LI.getVNInfoBefore(LIS->getMBBEndIdx(BB));
    if (!DefVNI)
      continue;

    MachineInstr *DefMI = LIS->getInstructionFromIndex(DefVNI->def);
    const SUnit *DefSU = getSUnit(DefMI);
    if (!DefSU)
      continue;

    unsigned LiveOutHeight = DefSU->getHeight();
    unsigned LiveOutDepth = DefSU->getDepth() + DefSU->Latency;
    // Visit all local users of the vreg def.
    for (const VReg2SUnit &V2SU
         : make_range(VRegUses.find(Reg), VRegUses.end())) {
      SUnit *SU = V2SU.SU;
      if (SU == &ExitSU)
        continue;

      // Only consider uses of the phi.
      LiveQueryResult LRQ = LI.Query(LIS->getInstructionIndex(*SU->getInstr()));
      if (!LRQ.valueIn()->isPHIDef())
        continue;

      // Assume that a path spanning two iterations is a cycle, which could
      // overestimate in strange cases. This allows cyclic latency to be
      // estimated as the minimum slack of the vreg's depth or height.
      unsigned CyclicLatency = 0;
      if (LiveOutDepth > SU->getDepth())
        CyclicLatency = LiveOutDepth - SU->getDepth();

      unsigned LiveInHeight = SU->getHeight() + DefSU->Latency;
      if (LiveInHeight > LiveOutHeight) {
        if (LiveInHeight - LiveOutHeight < CyclicLatency)
          CyclicLatency = LiveInHeight - LiveOutHeight;
      } else
        CyclicLatency = 0;

      LLVM_DEBUG(dbgs() << "Cyclic Path: SU(" << DefSU->NodeNum << ") -> SU("
                        << SU->NodeNum << ") = " << CyclicLatency << "c\n");
      if (CyclicLatency > MaxCyclicLatency)
        MaxCyclicLatency = CyclicLatency;
    }
  }
  LLVM_DEBUG(dbgs() << "Cyclic Critical Path: " << MaxCyclicLatency << "c\n");
  return MaxCyclicLatency;
}

/// Release ExitSU predecessors and setup scheduler queues. Re-position
/// the Top RP tracker in case the region beginning has changed.
void ScheduleDAGMILive::initQueues(ArrayRef<SUnit*> TopRoots,
                                   ArrayRef<SUnit*> BotRoots) {
  ScheduleDAGMI::initQueues(TopRoots, BotRoots);
  if (ShouldTrackPressure) {
    assert(TopRPTracker.getPos() == RegionBegin && "bad initial Top tracker");
    TopRPTracker.setPos(CurrentTop);
  }
}

/// Move an instruction and update register pressure.
void ScheduleDAGMILive::scheduleMI(SUnit *SU, bool IsTopNode) {
  // Move the instruction to its new location in the instruction stream.
  MachineInstr *MI = SU->getInstr();

  if (IsTopNode) {
    assert(SU->isTopReady() && "node still has unscheduled dependencies");
    if (&*CurrentTop == MI)
      CurrentTop = nextIfDebug(++CurrentTop, CurrentBottom);
    else {
      moveInstruction(MI, CurrentTop);
      TopRPTracker.setPos(MI);
    }

    if (ShouldTrackPressure) {
      // Update top scheduled pressure.
      RegisterOperands RegOpers;
      RegOpers.collect(*MI, *TRI, MRI, ShouldTrackLaneMasks,
                       /*IgnoreDead=*/false);
      if (ShouldTrackLaneMasks) {
        // Adjust liveness and add missing dead+read-undef flags.
        SlotIndex SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot();
        RegOpers.adjustLaneLiveness(*LIS, MRI, SlotIdx, MI);
      } else {
        // Adjust for missing dead-def flags.
        RegOpers.detectDeadDefs(*MI, *LIS);
      }

      TopRPTracker.advance(RegOpers);
      assert(TopRPTracker.getPos() == CurrentTop && "out of sync");
      LLVM_DEBUG(dbgs() << "Top Pressure: "; dumpRegSetPressure(
                     TopRPTracker.getRegSetPressureAtPos(), TRI););

      updateScheduledPressure(SU, TopRPTracker.getPressure().MaxSetPressure);
    }
  } else {
    assert(SU->isBottomReady() && "node still has unscheduled dependencies");
    MachineBasicBlock::iterator priorII =
      priorNonDebug(CurrentBottom, CurrentTop);
    if (&*priorII == MI)
      CurrentBottom = priorII;
    else {
      if (&*CurrentTop == MI) {
        CurrentTop = nextIfDebug(++CurrentTop, priorII);
        TopRPTracker.setPos(CurrentTop);
      }
      moveInstruction(MI, CurrentBottom);
      CurrentBottom = MI;
      BotRPTracker.setPos(CurrentBottom);
    }
    if (ShouldTrackPressure) {
      RegisterOperands RegOpers;
      RegOpers.collect(*MI, *TRI, MRI, ShouldTrackLaneMasks,
                       /*IgnoreDead=*/false);
      if (ShouldTrackLaneMasks) {
        // Adjust liveness and add missing dead+read-undef flags.
        SlotIndex SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot();
        RegOpers.adjustLaneLiveness(*LIS, MRI, SlotIdx, MI);
      } else {
        // Adjust for missing dead-def flags.
        RegOpers.detectDeadDefs(*MI, *LIS);
      }

      if (BotRPTracker.getPos() != CurrentBottom)
        BotRPTracker.recedeSkipDebugValues();
      SmallVector<VRegMaskOrUnit, 8> LiveUses;
      BotRPTracker.recede(RegOpers, &LiveUses);
      assert(BotRPTracker.getPos() == CurrentBottom && "out of sync");
      LLVM_DEBUG(dbgs() << "Bottom Pressure: "; dumpRegSetPressure(
                     BotRPTracker.getRegSetPressureAtPos(), TRI););

      updateScheduledPressure(SU, BotRPTracker.getPressure().MaxSetPressure);
      updatePressureDiffs(LiveUses);
    }
  }
}

//===----------------------------------------------------------------------===//
// BaseMemOpClusterMutation - DAG post-processing to cluster loads or stores.
//===----------------------------------------------------------------------===//

namespace {

/// Post-process the DAG to create cluster edges between neighboring
/// loads or between neighboring stores.
class BaseMemOpClusterMutation : public ScheduleDAGMutation {
  struct MemOpInfo {
    SUnit *SU;
    SmallVector<const MachineOperand *, 4> BaseOps;
    int64_t Offset;
    LocationSize Width;
    bool OffsetIsScalable;

    MemOpInfo(SUnit *SU, ArrayRef<const MachineOperand *> BaseOps,
              int64_t Offset, bool OffsetIsScalable, LocationSize Width)
        : SU(SU), BaseOps(BaseOps), Offset(Offset), Width(Width),
          OffsetIsScalable(OffsetIsScalable) {}

    static bool Compare(const MachineOperand *const &A,
                        const MachineOperand *const &B) {
      if (A->getType() != B->getType())
        return A->getType() < B->getType();
      if (A->isReg())
        return A->getReg() < B->getReg();
      if (A->isFI()) {
        const MachineFunction &MF = *A->getParent()->getParent()->getParent();
        const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
        bool StackGrowsDown = TFI.getStackGrowthDirection() ==
                              TargetFrameLowering::StackGrowsDown;
        return StackGrowsDown ? A->getIndex() > B->getIndex()
                              : A->getIndex() < B->getIndex();
      }

      llvm_unreachable("MemOpClusterMutation only supports register or frame "
                       "index bases.");
    }

    bool operator<(const MemOpInfo &RHS) const {
      // FIXME: Don't compare everything twice. Maybe use C++20 three way
      // comparison instead when it's available.
      if (std::lexicographical_compare(BaseOps.begin(), BaseOps.end(),
                                       RHS.BaseOps.begin(), RHS.BaseOps.end(),
                                       Compare))
        return true;
      if (std::lexicographical_compare(RHS.BaseOps.begin(), RHS.BaseOps.end(),
                                       BaseOps.begin(), BaseOps.end(), Compare))
        return false;
      if (Offset != RHS.Offset)
        return Offset < RHS.Offset;
      return SU->NodeNum < RHS.SU->NodeNum;
    }
  };

  const TargetInstrInfo *TII;
  const TargetRegisterInfo *TRI;
  bool IsLoad;
  bool ReorderWhileClustering;

public:
  BaseMemOpClusterMutation(const TargetInstrInfo *tii,
                           const TargetRegisterInfo *tri, bool IsLoad,
                           bool ReorderWhileClustering)
      : TII(tii), TRI(tri), IsLoad(IsLoad),
        ReorderWhileClustering(ReorderWhileClustering) {}

  void apply(ScheduleDAGInstrs *DAGInstrs) override;

protected:
  void clusterNeighboringMemOps(ArrayRef<MemOpInfo> MemOps, bool FastCluster,
                                ScheduleDAGInstrs *DAG);
  void collectMemOpRecords(std::vector<SUnit> &SUnits,
                           SmallVectorImpl<MemOpInfo> &MemOpRecords);
  bool groupMemOps(ArrayRef<MemOpInfo> MemOps, ScheduleDAGInstrs *DAG,
                   DenseMap<unsigned, SmallVector<MemOpInfo, 32>> &Groups);
};

class StoreClusterMutation : public BaseMemOpClusterMutation {
public:
  StoreClusterMutation(const TargetInstrInfo *tii,
                       const TargetRegisterInfo *tri,
                       bool ReorderWhileClustering)
      : BaseMemOpClusterMutation(tii, tri, false, ReorderWhileClustering) {}
};

class LoadClusterMutation : public BaseMemOpClusterMutation {
public:
  LoadClusterMutation(const TargetInstrInfo *tii, const TargetRegisterInfo *tri,
                      bool ReorderWhileClustering)
      : BaseMemOpClusterMutation(tii, tri, true, ReorderWhileClustering) {}
};

} // end anonymous namespace

namespace llvm {

std::unique_ptr<ScheduleDAGMutation>
createLoadClusterDAGMutation(const TargetInstrInfo *TII,
                             const TargetRegisterInfo *TRI,
                             bool ReorderWhileClustering) {
  return EnableMemOpCluster ? std::make_unique<LoadClusterMutation>(
                                  TII, TRI, ReorderWhileClustering)
                            : nullptr;
}

std::unique_ptr<ScheduleDAGMutation>
createStoreClusterDAGMutation(const TargetInstrInfo *TII,
                              const TargetRegisterInfo *TRI,
                              bool ReorderWhileClustering) {
  return EnableMemOpCluster ? std::make_unique<StoreClusterMutation>(
                                  TII, TRI, ReorderWhileClustering)
                            : nullptr;
}

} // end namespace llvm

// Sorting all the loads/stores first, then for each load/store, checking the
// following load/store one by one, until reach the first non-dependent one and
// call target hook to see if they can cluster.
// If FastCluster is enabled, we assume that, all the loads/stores have been
// preprocessed and now, they didn't have dependencies on each other.
void BaseMemOpClusterMutation::clusterNeighboringMemOps(
    ArrayRef<MemOpInfo> MemOpRecords, bool FastCluster,
    ScheduleDAGInstrs *DAG) {
  // Keep track of the current cluster length and bytes for each SUnit.
  DenseMap<unsigned, std::pair<unsigned, unsigned>> SUnit2ClusterInfo;
  EquivalenceClasses<SUnit *> Clusters;

  // At this point, `MemOpRecords` array must hold atleast two mem ops. Try to
  // cluster mem ops collected within `MemOpRecords` array.
  for (unsigned Idx = 0, End = MemOpRecords.size(); Idx < (End - 1); ++Idx) {
    // Decision to cluster mem ops is taken based on target dependent logic
    auto MemOpa = MemOpRecords[Idx];

    // Seek for the next load/store to do the cluster.
    unsigned NextIdx = Idx + 1;
    for (; NextIdx < End; ++NextIdx)
      // Skip if MemOpb has been clustered already or has dependency with
      // MemOpa.
      if (!SUnit2ClusterInfo.count(MemOpRecords[NextIdx].SU->NodeNum) &&
          (FastCluster ||
           (!DAG->IsReachable(MemOpRecords[NextIdx].SU, MemOpa.SU) &&
            !DAG->IsReachable(MemOpa.SU, MemOpRecords[NextIdx].SU))))
        break;
    if (NextIdx == End)
      continue;

    auto MemOpb = MemOpRecords[NextIdx];
    unsigned ClusterLength = 2;
    unsigned CurrentClusterBytes = MemOpa.Width.getValue().getKnownMinValue() +
                                   MemOpb.Width.getValue().getKnownMinValue();
    auto It = SUnit2ClusterInfo.find(MemOpa.SU->NodeNum);
    if (It != SUnit2ClusterInfo.end()) {
      const auto &[Len, Bytes] = It->second;
      ClusterLength = Len + 1;
      CurrentClusterBytes = Bytes + MemOpb.Width.getValue().getKnownMinValue();
    }

    if (!TII->shouldClusterMemOps(MemOpa.BaseOps, MemOpa.Offset,
                                  MemOpa.OffsetIsScalable, MemOpb.BaseOps,
                                  MemOpb.Offset, MemOpb.OffsetIsScalable,
                                  ClusterLength, CurrentClusterBytes))
      continue;

    SUnit *SUa = MemOpa.SU;
    SUnit *SUb = MemOpb.SU;

    if (!ReorderWhileClustering && SUa->NodeNum > SUb->NodeNum)
      std::swap(SUa, SUb);

    // FIXME: Is this check really required?
    if (!DAG->addEdge(SUb, SDep(SUa, SDep::Cluster)))
      continue;

    Clusters.unionSets(SUa, SUb);
    LLVM_DEBUG(dbgs() << "Cluster ld/st SU(" << SUa->NodeNum << ") - SU("
                      << SUb->NodeNum << ")\n");
    ++NumClustered;

    if (IsLoad) {
      // Copy successor edges from SUa to SUb. Interleaving computation
      // dependent on SUa can prevent load combining due to register reuse.
      // Predecessor edges do not need to be copied from SUb to SUa since
      // nearby loads should have effectively the same inputs.
      for (const SDep &Succ : SUa->Succs) {
        if (Succ.getSUnit() == SUb)
          continue;
        LLVM_DEBUG(dbgs() << "  Copy Succ SU(" << Succ.getSUnit()->NodeNum
                          << ")\n");
        DAG->addEdge(Succ.getSUnit(), SDep(SUb, SDep::Artificial));
      }
    } else {
      // Copy predecessor edges from SUb to SUa to avoid the SUnits that
      // SUb dependent on scheduled in-between SUb and SUa. Successor edges
      // do not need to be copied from SUa to SUb since no one will depend
      // on stores.
      // Notice that, we don't need to care about the memory dependency as
      // we won't try to cluster them if they have any memory dependency.
      for (const SDep &Pred : SUb->Preds) {
        if (Pred.getSUnit() == SUa)
          continue;
        LLVM_DEBUG(dbgs() << "  Copy Pred SU(" << Pred.getSUnit()->NodeNum
                          << ")\n");
        DAG->addEdge(SUa, SDep(Pred.getSUnit(), SDep::Artificial));
      }
    }

    SUnit2ClusterInfo[MemOpb.SU->NodeNum] = {ClusterLength,
                                             CurrentClusterBytes};

    LLVM_DEBUG(dbgs() << "  Curr cluster length: " << ClusterLength
                      << ", Curr cluster bytes: " << CurrentClusterBytes
                      << "\n");
  }

  // Add cluster group information.
  // Iterate over all of the equivalence sets.
  auto &AllClusters = DAG->getClusters();
  for (const EquivalenceClasses<SUnit *>::ECValue *I : Clusters) {
    if (!I->isLeader())
      continue;
    ClusterInfo Group;
    unsigned ClusterIdx = AllClusters.size();
    for (SUnit *MemberI : Clusters.members(*I)) {
      MemberI->ParentClusterIdx = ClusterIdx;
      Group.insert(MemberI);
    }
    AllClusters.push_back(Group);
  }
}

void BaseMemOpClusterMutation::collectMemOpRecords(
    std::vector<SUnit> &SUnits, SmallVectorImpl<MemOpInfo> &MemOpRecords) {
  for (auto &SU : SUnits) {
    if ((IsLoad && !SU.getInstr()->mayLoad()) ||
        (!IsLoad && !SU.getInstr()->mayStore()))
      continue;

    const MachineInstr &MI = *SU.getInstr();
    SmallVector<const MachineOperand *, 4> BaseOps;
    int64_t Offset;
    bool OffsetIsScalable;
    LocationSize Width = LocationSize::precise(0);
    if (TII->getMemOperandsWithOffsetWidth(MI, BaseOps, Offset,
                                           OffsetIsScalable, Width, TRI)) {
      if (!Width.hasValue())
        continue;

      MemOpRecords.push_back(
          MemOpInfo(&SU, BaseOps, Offset, OffsetIsScalable, Width));

      LLVM_DEBUG(dbgs() << "Num BaseOps: " << BaseOps.size() << ", Offset: "
                        << Offset << ", OffsetIsScalable: " << OffsetIsScalable
                        << ", Width: " << Width << "\n");
    }
#ifndef NDEBUG
    for (const auto *Op : BaseOps)
      assert(Op);
#endif
  }
}

bool BaseMemOpClusterMutation::groupMemOps(
    ArrayRef<MemOpInfo> MemOps, ScheduleDAGInstrs *DAG,
    DenseMap<unsigned, SmallVector<MemOpInfo, 32>> &Groups) {
  bool FastCluster =
      ForceFastCluster ||
      MemOps.size() * DAG->SUnits.size() / 1000 > FastClusterThreshold;

  for (const auto &MemOp : MemOps) {
    unsigned ChainPredID = DAG->SUnits.size();
    if (FastCluster) {
      for (const SDep &Pred : MemOp.SU->Preds) {
        // We only want to cluster the mem ops that have the same ctrl(non-data)
        // pred so that they didn't have ctrl dependency for each other. But for
        // store instrs, we can still cluster them if the pred is load instr.
        if ((Pred.isCtrl() &&
             (IsLoad ||
              (Pred.getSUnit() && Pred.getSUnit()->getInstr()->mayStore()))) &&
            !Pred.isArtificial()) {
          ChainPredID = Pred.getSUnit()->NodeNum;
          break;
        }
      }
    } else
      ChainPredID = 0;

    Groups[ChainPredID].push_back(MemOp);
  }
  return FastCluster;
}

/// Callback from DAG postProcessing to create cluster edges for loads/stores.
void BaseMemOpClusterMutation::apply(ScheduleDAGInstrs *DAG) {
  // Collect all the clusterable loads/stores
  SmallVector<MemOpInfo, 32> MemOpRecords;
  collectMemOpRecords(DAG->SUnits, MemOpRecords);

  if (MemOpRecords.size() < 2)
    return;

  // Put the loads/stores without dependency into the same group with some
  // heuristic if the DAG is too complex to avoid compiling time blow up.
  // Notice that, some fusion pair could be lost with this.
  DenseMap<unsigned, SmallVector<MemOpInfo, 32>> Groups;
  bool FastCluster = groupMemOps(MemOpRecords, DAG, Groups);

  for (auto &Group : Groups) {
    // Sorting the loads/stores, so that, we can stop the cluster as early as
    // possible.
    llvm::sort(Group.second);

    // Trying to cluster all the neighboring loads/stores.
    clusterNeighboringMemOps(Group.second, FastCluster, DAG);
  }
}

//===----------------------------------------------------------------------===//
// CopyConstrain - DAG post-processing to encourage copy elimination.
//===----------------------------------------------------------------------===//

namespace {

/// Post-process the DAG to create weak edges from all uses of a copy to
/// the one use that defines the copy's source vreg, most likely an induction
/// variable increment.
class CopyConstrain : public ScheduleDAGMutation {
  // Transient state.
  SlotIndex RegionBeginIdx;

  // RegionEndIdx is the slot index of the last non-debug instruction in the
  // scheduling region. So we may have RegionBeginIdx == RegionEndIdx.
  SlotIndex RegionEndIdx;

public:
  CopyConstrain(const TargetInstrInfo *, const TargetRegisterInfo *) {}

  void apply(ScheduleDAGInstrs *DAGInstrs) override;

protected:
  void constrainLocalCopy(SUnit *CopySU, ScheduleDAGMILive *DAG);
};

} // end anonymous namespace

namespace llvm {

std::unique_ptr<ScheduleDAGMutation>
createCopyConstrainDAGMutation(const TargetInstrInfo *TII,
                               const TargetRegisterInfo *TRI) {
  return std::make_unique<CopyConstrain>(TII, TRI);
}

} // end namespace llvm

/// constrainLocalCopy handles two possibilities:
/// 1) Local src:
/// I0:     = dst
/// I1: src = ...
/// I2:     = dst
/// I3: dst = src (copy)
/// (create pred->succ edges I0->I1, I2->I1)
///
/// 2) Local copy:
/// I0: dst = src (copy)
/// I1:     = dst
/// I2: src = ...
/// I3:     = dst
/// (create pred->succ edges I1->I2, I3->I2)
///
/// Although the MachineScheduler is currently constrained to single blocks,
/// this algorithm should handle extended blocks. An EBB is a set of
/// contiguously numbered blocks such that the previous block in the EBB is
/// always the single predecessor.
void CopyConstrain::constrainLocalCopy(SUnit *CopySU, ScheduleDAGMILive *DAG) {
  LiveIntervals *LIS = DAG->getLIS();
  MachineInstr *Copy = CopySU->getInstr();

  // Check for pure vreg copies.
  const MachineOperand &SrcOp = Copy->getOperand(1);
  Register SrcReg = SrcOp.getReg();
  if (!SrcReg.isVirtual() || !SrcOp.readsReg())
    return;

  const MachineOperand &DstOp = Copy->getOperand(0);
  Register DstReg = DstOp.getReg();
  if (!DstReg.isVirtual() || DstOp.isDead())
    return;

  // Check if either the dest or source is local. If it's live across a back
  // edge, it's not local. Note that if both vregs are live across the back
  // edge, we cannot successfully contrain the copy without cyclic scheduling.
  // If both the copy's source and dest are local live intervals, then we
  // should treat the dest as the global for the purpose of adding
  // constraints. This adds edges from source's other uses to the copy.
  unsigned LocalReg = SrcReg;
  unsigned GlobalReg = DstReg;
  LiveInterval *LocalLI = &LIS->getInterval(LocalReg);
  if (!LocalLI->isLocal(RegionBeginIdx, RegionEndIdx)) {
    LocalReg = DstReg;
    GlobalReg = SrcReg;
    LocalLI = &LIS->getInterval(LocalReg);
    if (!LocalLI->isLocal(RegionBeginIdx, RegionEndIdx))
      return;
  }
  LiveInterval *GlobalLI = &LIS->getInterval(GlobalReg);

  // Find the global segment after the start of the local LI.
  LiveInterval::iterator GlobalSegment = GlobalLI->find(LocalLI->beginIndex());
  // If GlobalLI does not overlap LocalLI->start, then a copy directly feeds a
  // local live range. We could create edges from other global uses to the local
  // start, but the coalescer should have already eliminated these cases, so
  // don't bother dealing with it.
  if (GlobalSegment == GlobalLI->end())
    return;

  // If GlobalSegment is killed at the LocalLI->start, the call to find()
  // returned the next global segment. But if GlobalSegment overlaps with
  // LocalLI->start, then advance to the next segment. If a hole in GlobalLI
  // exists in LocalLI's vicinity, GlobalSegment will be the end of the hole.
  if (GlobalSegment->contains(LocalLI->beginIndex()))
    ++GlobalSegment;

  if (GlobalSegment == GlobalLI->end())
    return;

  // Check if GlobalLI contains a hole in the vicinity of LocalLI.
  if (GlobalSegment != GlobalLI->begin()) {
    // Two address defs have no hole.
    if (SlotIndex::isSameInstr(std::prev(GlobalSegment)->end,
                               GlobalSegment->start)) {
      return;
    }
    // If the prior global segment may be defined by the same two-address
    // instruction that also defines LocalLI, then can't make a hole here.
    if (SlotIndex::isSameInstr(std::prev(GlobalSegment)->start,
                               LocalLI->beginIndex())) {
      return;
    }
    // If GlobalLI has a prior segment, it must be live into the EBB. Otherwise
    // it would be a disconnected component in the live range.
    assert(std::prev(GlobalSegment)->start < LocalLI->beginIndex() &&
           "Disconnected LRG within the scheduling region.");
  }
  MachineInstr *GlobalDef = LIS->getInstructionFromIndex(GlobalSegment->start);
  if (!GlobalDef)
    return;

  SUnit *GlobalSU = DAG->getSUnit(GlobalDef);
  if (!GlobalSU)
    return;

  // GlobalDef is the bottom of the GlobalLI hole. Open the hole by
  // constraining the uses of the last local def to precede GlobalDef.
  SmallVector<SUnit*,8> LocalUses;
  const VNInfo *LastLocalVN = LocalLI->getVNInfoBefore(LocalLI->endIndex());
  MachineInstr *LastLocalDef = LIS->getInstructionFromIndex(LastLocalVN->def);
  SUnit *LastLocalSU = DAG->getSUnit(LastLocalDef);
  for (const SDep &Succ : LastLocalSU->Succs) {
    if (Succ.getKind() != SDep::Data || Succ.getReg() != LocalReg)
      continue;
    if (Succ.getSUnit() == GlobalSU)
      continue;
    if (!DAG->canAddEdge(GlobalSU, Succ.getSUnit()))
      return;
    LocalUses.push_back(Succ.getSUnit());
  }
  // Open the top of the GlobalLI hole by constraining any earlier global uses
  // to precede the start of LocalLI.
  SmallVector<SUnit*,8> GlobalUses;
  MachineInstr *FirstLocalDef =
    LIS->getInstructionFromIndex(LocalLI->beginIndex());
  SUnit *FirstLocalSU = DAG->getSUnit(FirstLocalDef);
  for (const SDep &Pred : GlobalSU->Preds) {
    if (Pred.getKind() != SDep::Anti || Pred.getReg() != GlobalReg)
      continue;
    if (Pred.getSUnit() == FirstLocalSU)
      continue;
    if (!DAG->canAddEdge(FirstLocalSU, Pred.getSUnit()))
      return;
    GlobalUses.push_back(Pred.getSUnit());
  }
  LLVM_DEBUG(dbgs() << "Constraining copy SU(" << CopySU->NodeNum << ")\n");
  // Add the weak edges.
  for (SUnit *LU : LocalUses) {
    LLVM_DEBUG(dbgs() << "  Local use SU(" << LU->NodeNum << ") -> SU("
                      << GlobalSU->NodeNum << ")\n");
    DAG->addEdge(GlobalSU, SDep(LU, SDep::Weak));
  }
  for (SUnit *GU : GlobalUses) {
    LLVM_DEBUG(dbgs() << "  Global use SU(" << GU->NodeNum << ") -> SU("
                      << FirstLocalSU->NodeNum << ")\n");
    DAG->addEdge(FirstLocalSU, SDep(GU, SDep::Weak));
  }
}

/// Callback from DAG postProcessing to create weak edges to encourage
/// copy elimination.
void CopyConstrain::apply(ScheduleDAGInstrs *DAGInstrs) {
  ScheduleDAGMI *DAG = static_cast<ScheduleDAGMI*>(DAGInstrs);
  assert(DAG->hasVRegLiveness() && "Expect VRegs with LiveIntervals");

  MachineBasicBlock::iterator FirstPos = nextIfDebug(DAG->begin(), DAG->end());
  if (FirstPos == DAG->end())
    return;
  RegionBeginIdx = DAG->getLIS()->getInstructionIndex(*FirstPos);
  RegionEndIdx = DAG->getLIS()->getInstructionIndex(
      *priorNonDebug(DAG->end(), DAG->begin()));

  for (SUnit &SU : DAG->SUnits) {
    if (!SU.getInstr()->isCopy())
      continue;

    constrainLocalCopy(&SU, static_cast<ScheduleDAGMILive*>(DAG));
  }
}

//===----------------------------------------------------------------------===//
// MachineSchedStrategy helpers used by GenericScheduler, GenericPostScheduler
// and possibly other custom schedulers.
//===----------------------------------------------------------------------===//

static const unsigned InvalidCycle = ~0U;

SchedBoundary::~SchedBoundary() { delete HazardRec; }

/// Given a Count of resource usage and a Latency value, return true if a
/// SchedBoundary becomes resource limited.
/// If we are checking after scheduling a node, we should return true when
/// we just reach the resource limit.
static bool checkResourceLimit(unsigned LFactor, unsigned Count,
                               unsigned Latency, bool AfterSchedNode) {
  int ResCntFactor = (int)(Count - (Latency * LFactor));
  if (AfterSchedNode)
    return ResCntFactor >= (int)LFactor;
  else
    return ResCntFactor > (int)LFactor;
}

void SchedBoundary::reset() {
  // A new HazardRec is created for each DAG and owned by SchedBoundary.
  // Destroying and reconstructing it is very expensive though. So keep
  // invalid, placeholder HazardRecs.
  if (HazardRec && HazardRec->isEnabled()) {
    delete HazardRec;
    HazardRec = nullptr;
  }
  Available.clear();
  Pending.clear();
  CheckPending = false;
  CurrCycle = 0;
  CurrMOps = 0;
  MinReadyCycle = std::numeric_limits<unsigned>::max();
  ExpectedLatency = 0;
  DependentLatency = 0;
  RetiredMOps = 0;
  MaxExecutedResCount = 0;
  ZoneCritResIdx = 0;
  IsResourceLimited = false;
  ReservedCycles.clear();
  ReservedResourceSegments.clear();
  ReservedCyclesIndex.clear();
  ResourceGroupSubUnitMasks.clear();
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
  // Track the maximum number of stall cycles that could arise either from the
  // latency of a DAG edge or the number of cycles that a processor resource is
  // reserved (SchedBoundary::ReservedCycles).
  MaxObservedStall = 0;
#endif
  // Reserve a zero-count for invalid CritResIdx.
  ExecutedResCounts.resize(1);
  assert(!ExecutedResCounts[0] && "nonzero count for bad resource");
}

void SchedRemainder::
init(ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel) {
  reset();
  if (!SchedModel->hasInstrSchedModel())
    return;
  RemainingCounts.resize(SchedModel->getNumProcResourceKinds());
  for (SUnit &SU : DAG->SUnits) {
    const MCSchedClassDesc *SC = DAG->getSchedClass(&SU);
    RemIssueCount += SchedModel->getNumMicroOps(SU.getInstr(), SC)
      * SchedModel->getMicroOpFactor();
    for (TargetSchedModel::ProcResIter
           PI = SchedModel->getWriteProcResBegin(SC),
           PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {
      unsigned PIdx = PI->ProcResourceIdx;
      unsigned Factor = SchedModel->getResourceFactor(PIdx);
      assert(PI->ReleaseAtCycle >= PI->AcquireAtCycle);
      RemainingCounts[PIdx] +=
          (Factor * (PI->ReleaseAtCycle - PI->AcquireAtCycle));
    }
  }
}

void SchedBoundary::
init(ScheduleDAGMI *dag, const TargetSchedModel *smodel, SchedRemainder *rem) {
  reset();
  DAG = dag;
  SchedModel = smodel;
  Rem = rem;
  if (SchedModel->hasInstrSchedModel()) {
    unsigned ResourceCount = SchedModel->getNumProcResourceKinds();
    ReservedCyclesIndex.resize(ResourceCount);
    ExecutedResCounts.resize(ResourceCount);
    ResourceGroupSubUnitMasks.resize(ResourceCount, APInt(ResourceCount, 0));
    unsigned NumUnits = 0;

    for (unsigned i = 0; i < ResourceCount; ++i) {
      ReservedCyclesIndex[i] = NumUnits;
      NumUnits += SchedModel->getProcResource(i)->NumUnits;
      if (isUnbufferedGroup(i)) {
        auto SubUnits = SchedModel->getProcResource(i)->SubUnitsIdxBegin;
        for (unsigned U = 0, UE = SchedModel->getProcResource(i)->NumUnits;
             U != UE; ++U)
          ResourceGroupSubUnitMasks[i].setBit(SubUnits[U]);
      }
    }

    ReservedCycles.resize(NumUnits, InvalidCycle);
  }
}

/// Compute the stall cycles based on this SUnit's ready time. Heuristics treat
/// these "soft stalls" differently than the hard stall cycles based on CPU
/// resources and computed by checkHazard(). A fully in-order model
/// (MicroOpBufferSize==0) will not make use of this since instructions are not
/// available for scheduling until they are ready. However, a weaker in-order
/// model may use this for heuristics. For example, if a processor has in-order
/// behavior when reading certain resources, this may come into play.
unsigned SchedBoundary::getLatencyStallCycles(SUnit *SU) {
  if (!SU->isUnbuffered)
    return 0;

  unsigned ReadyCycle = (isTop() ? SU->TopReadyCycle : SU->BotReadyCycle);
  if (ReadyCycle > CurrCycle)
    return ReadyCycle - CurrCycle;
  return 0;
}

/// Compute the next cycle at which the given processor resource unit
/// can be scheduled.
unsigned SchedBoundary::getNextResourceCycleByInstance(unsigned InstanceIdx,
                                                       unsigned ReleaseAtCycle,
                                                       unsigned AcquireAtCycle) {
  if (SchedModel && SchedModel->enableIntervals()) {
    if (isTop())
      return ReservedResourceSegments[InstanceIdx].getFirstAvailableAtFromTop(
          CurrCycle, AcquireAtCycle, ReleaseAtCycle);

    return ReservedResourceSegments[InstanceIdx].getFirstAvailableAtFromBottom(
        CurrCycle, AcquireAtCycle, ReleaseAtCycle);
  }

  unsigned NextUnreserved = ReservedCycles[InstanceIdx];
  // If this resource has never been used, always return cycle zero.
  if (NextUnreserved == InvalidCycle)
    return CurrCycle;
  // For bottom-up scheduling add the cycles needed for the current operation.
  if (!isTop())
    NextUnreserved = std::max(CurrCycle, NextUnreserved + ReleaseAtCycle);
  return NextUnreserved;
}

/// Compute the next cycle at which the given processor resource can be
/// scheduled.  Returns the next cycle and the index of the processor resource
/// instance in the reserved cycles vector.
std::pair<unsigned, unsigned>
SchedBoundary::getNextResourceCycle(const MCSchedClassDesc *SC, unsigned PIdx,
                                    unsigned ReleaseAtCycle,
                                    unsigned AcquireAtCycle) {
  if (MischedDetailResourceBooking) {
    LLVM_DEBUG(dbgs() << "  Resource booking (@" << CurrCycle << "c): \n");
    LLVM_DEBUG(dumpReservedCycles());
    LLVM_DEBUG(dbgs() << "  getNextResourceCycle (@" << CurrCycle << "c): \n");
  }
  unsigned MinNextUnreserved = InvalidCycle;
  unsigned InstanceIdx = 0;
  unsigned StartIndex = ReservedCyclesIndex[PIdx];
  unsigned NumberOfInstances = SchedModel->getProcResource(PIdx)->NumUnits;
  assert(NumberOfInstances > 0 &&
         "Cannot have zero instances of a ProcResource");

  if (isUnbufferedGroup(PIdx)) {
    // If any subunits are used by the instruction, report that the
    // subunits of the resource group are available at the first cycle
    // in which the unit is available, effectively removing the group
    // record from hazarding and basing the hazarding decisions on the
    // subunit records. Otherwise, choose the first available instance
    // from among the subunits.  Specifications which assign cycles to
    // both the subunits and the group or which use an unbuffered
    // group with buffered subunits will appear to schedule
    // strangely. In the first case, the additional cycles for the
    // group will be ignored.  In the second, the group will be
    // ignored entirely.
    for (const MCWriteProcResEntry &PE :
         make_range(SchedModel->getWriteProcResBegin(SC),
                    SchedModel->getWriteProcResEnd(SC)))
      if (ResourceGroupSubUnitMasks[PIdx][PE.ProcResourceIdx])
        return std::make_pair(getNextResourceCycleByInstance(
                                  StartIndex, ReleaseAtCycle, AcquireAtCycle),
                              StartIndex);

    auto SubUnits = SchedModel->getProcResource(PIdx)->SubUnitsIdxBegin;
    for (unsigned I = 0, End = NumberOfInstances; I < End; ++I) {
      unsigned NextUnreserved, NextInstanceIdx;
      std::tie(NextUnreserved, NextInstanceIdx) =
          getNextResourceCycle(SC, SubUnits[I], ReleaseAtCycle, AcquireAtCycle);
      if (MinNextUnreserved > NextUnreserved) {
        InstanceIdx = NextInstanceIdx;
        MinNextUnreserved = NextUnreserved;
      }
    }
    return std::make_pair(MinNextUnreserved, InstanceIdx);
  }

  for (unsigned I = StartIndex, End = StartIndex + NumberOfInstances; I < End;
       ++I) {
    unsigned NextUnreserved =
        getNextResourceCycleByInstance(I, ReleaseAtCycle, AcquireAtCycle);
    if (MischedDetailResourceBooking)
      LLVM_DEBUG(dbgs() << "    Instance " << I - StartIndex << " available @"
                        << NextUnreserved << "c\n");
    if (MinNextUnreserved > NextUnreserved) {
      InstanceIdx = I;
      MinNextUnreserved = NextUnreserved;
    }
  }
  if (MischedDetailResourceBooking)
    LLVM_DEBUG(dbgs() << "    selecting " << SchedModel->getResourceName(PIdx)
                      << "[" << InstanceIdx - StartIndex << "]"
                      << " available @" << MinNextUnreserved << "c"
                      << "\n");
  return std::make_pair(MinNextUnreserved, InstanceIdx);
}

/// Does this SU have a hazard within the current instruction group.
///
/// The scheduler supports two modes of hazard recognition. The first is the
/// ScheduleHazardRecognizer API. It is a fully general hazard recognizer that
/// supports highly complicated in-order reservation tables
/// (ScoreboardHazardRecognizer) and arbitrary target-specific logic.
///
/// The second is a streamlined mechanism that checks for hazards based on
/// simple counters that the scheduler itself maintains. It explicitly checks
/// for instruction dispatch limitations, including the number of micro-ops that
/// can dispatch per cycle.
///
/// TODO: Also check whether the SU must start a new group.
bool SchedBoundary::checkHazard(SUnit *SU) {
  if (HazardRec->isEnabled()
      && HazardRec->getHazardType(SU) != ScheduleHazardRecognizer::NoHazard) {
    LLVM_DEBUG(dbgs().indent(2)
               << "hazard: SU(" << SU->NodeNum << ") reported by HazardRec\n");
    return true;
  }

  unsigned uops = SchedModel->getNumMicroOps(SU->getInstr());
  if ((CurrMOps > 0) && (CurrMOps + uops > SchedModel->getIssueWidth())) {
    LLVM_DEBUG(dbgs().indent(2) << "hazard:  SU(" << SU->NodeNum << ") uops="
                                << uops << ", CurrMOps = " << CurrMOps << ", "
                                << "CurrMOps + uops > issue width of "
                                << SchedModel->getIssueWidth() << "\n");
    return true;
  }

  if (CurrMOps > 0 &&
      ((isTop() && SchedModel->mustBeginGroup(SU->getInstr())) ||
       (!isTop() && SchedModel->mustEndGroup(SU->getInstr())))) {
    LLVM_DEBUG(dbgs().indent(2) << "hazard: SU(" << SU->NodeNum << ") must "
                                << (isTop() ? "begin" : "end") << " group\n");
    return true;
  }

  if (SchedModel->hasInstrSchedModel() && SU->hasReservedResource) {
    const MCSchedClassDesc *SC = DAG->getSchedClass(SU);
    for (const MCWriteProcResEntry &PE :
          make_range(SchedModel->getWriteProcResBegin(SC),
                     SchedModel->getWriteProcResEnd(SC))) {
      unsigned ResIdx = PE.ProcResourceIdx;
      unsigned ReleaseAtCycle = PE.ReleaseAtCycle;
      unsigned AcquireAtCycle = PE.AcquireAtCycle;
      unsigned NRCycle, InstanceIdx;
      std::tie(NRCycle, InstanceIdx) =
          getNextResourceCycle(SC, ResIdx, ReleaseAtCycle, AcquireAtCycle);
      if (NRCycle > CurrCycle) {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
        MaxObservedStall = std::max(ReleaseAtCycle, MaxObservedStall);
#endif
        LLVM_DEBUG(dbgs().indent(2)
                   << "hazard:  SU(" << SU->NodeNum << ") "
                   << SchedModel->getResourceName(ResIdx) << '['
                   << InstanceIdx - ReservedCyclesIndex[ResIdx] << ']' << "="
                   << NRCycle << "c, is later than "
                   << "CurrCycle = " << CurrCycle << "c\n");
        return true;
      }
    }
  }
  return false;
}

// Find the unscheduled node in ReadySUs with the highest latency.
unsigned SchedBoundary::
findMaxLatency(ArrayRef<SUnit*> ReadySUs) {
  SUnit *LateSU = nullptr;
  unsigned RemLatency = 0;
  for (SUnit *SU : ReadySUs) {
    unsigned L = getUnscheduledLatency(SU);
    if (L > RemLatency) {
      RemLatency = L;
      LateSU = SU;
    }
  }
  if (LateSU) {
    LLVM_DEBUG(dbgs() << Available.getName() << " RemLatency SU("
                      << LateSU->NodeNum << ") " << RemLatency << "c\n");
  }
  return RemLatency;
}

// Count resources in this zone and the remaining unscheduled
// instruction. Return the max count, scaled. Set OtherCritIdx to the critical
// resource index, or zero if the zone is issue limited.
unsigned SchedBoundary::
getOtherResourceCount(unsigned &OtherCritIdx) {
  OtherCritIdx = 0;
  if (!SchedModel->hasInstrSchedModel())
    return 0;

  unsigned OtherCritCount = Rem->RemIssueCount
    + (RetiredMOps * SchedModel->getMicroOpFactor());
  LLVM_DEBUG(dbgs() << "  " << Available.getName() << " + Remain MOps: "
                    << OtherCritCount / SchedModel->getMicroOpFactor() << '\n');
  for (unsigned PIdx = 1, PEnd = SchedModel->getNumProcResourceKinds();
       PIdx != PEnd; ++PIdx) {
    unsigned OtherCount = getResourceCount(PIdx) + Rem->RemainingCounts[PIdx];
    if (OtherCount > OtherCritCount) {
      OtherCritCount = OtherCount;
      OtherCritIdx = PIdx;
    }
  }
  if (OtherCritIdx) {
    LLVM_DEBUG(
        dbgs() << "  " << Available.getName() << " + Remain CritRes: "
               << OtherCritCount / SchedModel->getResourceFactor(OtherCritIdx)
               << " " << SchedModel->getResourceName(OtherCritIdx) << "\n");
  }
  return OtherCritCount;
}

void SchedBoundary::releaseNode(SUnit *SU, unsigned ReadyCycle, bool InPQueue,
                                unsigned Idx) {
  assert(SU->getInstr() && "Scheduled SUnit must have instr");

#if LLVM_ENABLE_ABI_BREAKING_CHECKS
  // ReadyCycle was been bumped up to the CurrCycle when this node was
  // scheduled, but CurrCycle may have been eagerly advanced immediately after
  // scheduling, so may now be greater than ReadyCycle.
  if (ReadyCycle > CurrCycle)
    MaxObservedStall = std::max(ReadyCycle - CurrCycle, MaxObservedStall);
#endif

  if (ReadyCycle < MinReadyCycle)
    MinReadyCycle = ReadyCycle;

  // Check for interlocks first. For the purpose of other heuristics, an
  // instruction that cannot issue appears as if it's not in the ReadyQueue.
  bool IsBuffered = SchedModel->getMicroOpBufferSize() != 0;
  bool HazardDetected = !IsBuffered && ReadyCycle > CurrCycle;
  if (HazardDetected)
    LLVM_DEBUG(dbgs().indent(2) << "hazard: SU(" << SU->NodeNum
                                << ") ReadyCycle = " << ReadyCycle
                                << " is later than CurrCycle = " << CurrCycle
                                << " on an unbuffered resource" << "\n");
  else
    HazardDetected = checkHazard(SU);

  if (!HazardDetected && Available.size() >= ReadyListLimit) {
    HazardDetected = true;
    LLVM_DEBUG(dbgs().indent(2) << "hazard: Available Q is full (size: "
                                << Available.size() << ")\n");
  }

  if (!HazardDetected) {
    Available.push(SU);
    LLVM_DEBUG(dbgs().indent(2)
               << "Move SU(" << SU->NodeNum << ") into Available Q\n");

    if (InPQueue)
      Pending.remove(Pending.begin() + Idx);
    return;
  }

  if (!InPQueue)
    Pending.push(SU);
}

/// Move the boundary of scheduled code by one cycle.
void SchedBoundary::bumpCycle(unsigned NextCycle) {
  if (SchedModel->getMicroOpBufferSize() == 0) {
    assert(MinReadyCycle < std::numeric_limits<unsigned>::max() &&
           "MinReadyCycle uninitialized");
    if (MinReadyCycle > NextCycle)
      NextCycle = MinReadyCycle;
  }
  // Update the current micro-ops, which will issue in the next cycle.
  unsigned DecMOps = SchedModel->getIssueWidth() * (NextCycle - CurrCycle);
  CurrMOps = (CurrMOps <= DecMOps) ? 0 : CurrMOps - DecMOps;

  // Decrement DependentLatency based on the next cycle.
  if ((NextCycle - CurrCycle) > DependentLatency)
    DependentLatency = 0;
  else
    DependentLatency -= (NextCycle - CurrCycle);

  if (!HazardRec->isEnabled()) {
    // Bypass HazardRec virtual calls.
    CurrCycle = NextCycle;
  } else {
    // Bypass getHazardType calls in case of long latency.
    for (; CurrCycle != NextCycle; ++CurrCycle) {
      if (isTop())
        HazardRec->AdvanceCycle();
      else
        HazardRec->RecedeCycle();
    }
  }
  CheckPending = true;
  IsResourceLimited =
      checkResourceLimit(SchedModel->getLatencyFactor(), getCriticalCount(),
                         getScheduledLatency(), true);

  LLVM_DEBUG(dbgs() << "Cycle: " << CurrCycle << ' ' << Available.getName()
                    << '\n');
}

void SchedBoundary::incExecutedResources(unsigned PIdx, unsigned Count) {
  ExecutedResCounts[PIdx] += Count;
  if (ExecutedResCounts[PIdx] > MaxExecutedResCount)
    MaxExecutedResCount = ExecutedResCounts[PIdx];
}

/// Add the given processor resource to this scheduled zone.
///
/// \param ReleaseAtCycle indicates the number of consecutive (non-pipelined)
/// cycles during which this resource is released.
///
/// \param AcquireAtCycle indicates the number of consecutive (non-pipelined)
/// cycles at which the resource is aquired after issue (assuming no stalls).
///
/// \return the next cycle at which the instruction may execute without
/// oversubscribing resources.
unsigned SchedBoundary::countResource(const MCSchedClassDesc *SC, unsigned PIdx,
                                      unsigned ReleaseAtCycle,
                                      unsigned NextCycle,
                                      unsigned AcquireAtCycle) {
  unsigned Factor = SchedModel->getResourceFactor(PIdx);
  unsigned Count = Factor * (ReleaseAtCycle- AcquireAtCycle);
  LLVM_DEBUG(dbgs() << "  " << SchedModel->getResourceName(PIdx) << " +"
                    << ReleaseAtCycle << "x" << Factor << "u\n");

  // Update Executed resources counts.
  incExecutedResources(PIdx, Count);
  assert(Rem->RemainingCounts[PIdx] >= Count && "resource double counted");
  Rem->RemainingCounts[PIdx] -= Count;

  // Check if this resource exceeds the current critical resource. If so, it
  // becomes the critical resource.
  if (ZoneCritResIdx != PIdx && (getResourceCount(PIdx) > getCriticalCount())) {
    ZoneCritResIdx = PIdx;
    LLVM_DEBUG(dbgs() << "  *** Critical resource "
                      << SchedModel->getResourceName(PIdx) << ": "
                      << getResourceCount(PIdx) / SchedModel->getLatencyFactor()
                      << "c\n");
  }
  // For reserved resources, record the highest cycle using the resource.
  unsigned NextAvailable, InstanceIdx;
  std::tie(NextAvailable, InstanceIdx) =
      getNextResourceCycle(SC, PIdx, ReleaseAtCycle, AcquireAtCycle);
  if (NextAvailable > CurrCycle) {
    LLVM_DEBUG(dbgs() << "  Resource conflict: "
                      << SchedModel->getResourceName(PIdx)
                      << '[' << InstanceIdx - ReservedCyclesIndex[PIdx]  << ']'
                      << " reserved until @" << NextAvailable << "\n");
  }
  return NextAvailable;
}

/// Move the boundary of scheduled code by one SUnit.
void SchedBoundary::bumpNode(SUnit *SU) {
  // Update the reservation table.
  if (HazardRec->isEnabled()) {
    if (!isTop() && SU->isCall) {
      // Calls are scheduled with their preceding instructions. For bottom-up
      // scheduling, clear the pipeline state before emitting.
      HazardRec->Reset();
    }
    HazardRec->EmitInstruction(SU);
    // Scheduling an instruction may have made pending instructions available.
    CheckPending = true;
  }
  // checkHazard should prevent scheduling multiple instructions per cycle that
  // exceed the issue width.
  const MCSchedClassDesc *SC = DAG->getSchedClass(SU);
  unsigned IncMOps = SchedModel->getNumMicroOps(SU->getInstr());
  assert(
      (CurrMOps == 0 || (CurrMOps + IncMOps) <= SchedModel->getIssueWidth()) &&
      "Cannot schedule this instruction's MicroOps in the current cycle.");

  unsigned ReadyCycle = (isTop() ? SU->TopReadyCycle : SU->BotReadyCycle);
  LLVM_DEBUG(dbgs() << "  Ready @" << ReadyCycle << "c\n");

  unsigned NextCycle = CurrCycle;
  switch (SchedModel->getMicroOpBufferSize()) {
  case 0:
    assert(ReadyCycle <= CurrCycle && "Broken PendingQueue");
    break;
  case 1:
    if (ReadyCycle > NextCycle) {
      NextCycle = ReadyCycle;
      LLVM_DEBUG(dbgs() << "  *** Stall until: " << ReadyCycle << "\n");
    }
    break;
  default:
    // We don't currently model the OOO reorder buffer, so consider all
    // scheduled MOps to be "retired". We do loosely model in-order resource
    // latency. If this instruction uses an in-order resource, account for any
    // likely stall cycles.
    if (SU->isUnbuffered && ReadyCycle > NextCycle)
      NextCycle = ReadyCycle;
    break;
  }
  RetiredMOps += IncMOps;

  // Update resource counts and critical resource.
  if (SchedModel->hasInstrSchedModel()) {
    unsigned DecRemIssue = IncMOps * SchedModel->getMicroOpFactor();
    assert(Rem->RemIssueCount >= DecRemIssue && "MOps double counted");
    Rem->RemIssueCount -= DecRemIssue;
    if (ZoneCritResIdx) {
      // Scale scheduled micro-ops for comparing with the critical resource.
      unsigned ScaledMOps =
        RetiredMOps * SchedModel->getMicroOpFactor();

      // If scaled micro-ops are now more than the previous critical resource by
      // a full cycle, then micro-ops issue becomes critical.
      if ((int)(ScaledMOps - getResourceCount(ZoneCritResIdx))
          >= (int)SchedModel->getLatencyFactor()) {
        ZoneCritResIdx = 0;
        LLVM_DEBUG(dbgs() << "  *** Critical resource NumMicroOps: "
                          << ScaledMOps / SchedModel->getLatencyFactor()
                          << "c\n");
      }
    }
    for (TargetSchedModel::ProcResIter
           PI = SchedModel->getWriteProcResBegin(SC),
           PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {
      unsigned RCycle =
          countResource(SC, PI->ProcResourceIdx, PI->ReleaseAtCycle, NextCycle,
                        PI->AcquireAtCycle);
      if (RCycle > NextCycle)
        NextCycle = RCycle;
    }
    if (SU->hasReservedResource) {
      // For reserved resources, record the highest cycle using the resource.
      // For top-down scheduling, this is the cycle in which we schedule this
      // instruction plus the number of cycles the operations reserves the
      // resource. For bottom-up is it simply the instruction's cycle.
      for (TargetSchedModel::ProcResIter
             PI = SchedModel->getWriteProcResBegin(SC),
             PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {
        unsigned PIdx = PI->ProcResourceIdx;
        if (SchedModel->getProcResource(PIdx)->BufferSize == 0) {

          if (SchedModel && SchedModel->enableIntervals()) {
            unsigned ReservedUntil, InstanceIdx;
            std::tie(ReservedUntil, InstanceIdx) = getNextResourceCycle(
                SC, PIdx, PI->ReleaseAtCycle, PI->AcquireAtCycle);
            if (isTop()) {
              ReservedResourceSegments[InstanceIdx].add(
                  ResourceSegments::getResourceIntervalTop(
                      NextCycle, PI->AcquireAtCycle, PI->ReleaseAtCycle),
                  MIResourceCutOff);
            } else {
              ReservedResourceSegments[InstanceIdx].add(
                  ResourceSegments::getResourceIntervalBottom(
                      NextCycle, PI->AcquireAtCycle, PI->ReleaseAtCycle),
                  MIResourceCutOff);
            }
          } else {

            unsigned ReservedUntil, InstanceIdx;
            std::tie(ReservedUntil, InstanceIdx) = getNextResourceCycle(
                SC, PIdx, PI->ReleaseAtCycle, PI->AcquireAtCycle);
            if (isTop()) {
              ReservedCycles[InstanceIdx] =
                  std::max(ReservedUntil, NextCycle + PI->ReleaseAtCycle);
            } else
              ReservedCycles[InstanceIdx] = NextCycle;
          }
        }
      }
    }
  }
  // Update ExpectedLatency and DependentLatency.
  unsigned &TopLatency = isTop() ? ExpectedLatency : DependentLatency;
  unsigned &BotLatency = isTop() ? DependentLatency : ExpectedLatency;
  if (SU->getDepth() > TopLatency) {
    TopLatency = SU->getDepth();
    LLVM_DEBUG(dbgs() << "  " << Available.getName() << " TopLatency SU("
                      << SU->NodeNum << ") " << TopLatency << "c\n");
  }
  if (SU->getHeight() > BotLatency) {
    BotLatency = SU->getHeight();
    LLVM_DEBUG(dbgs() << "  " << Available.getName() << " BotLatency SU("
                      << SU->NodeNum << ") " << BotLatency << "c\n");
  }
  // If we stall for any reason, bump the cycle.
  if (NextCycle > CurrCycle)
    bumpCycle(NextCycle);
  else
    // After updating ZoneCritResIdx and ExpectedLatency, check if we're
    // resource limited. If a stall occurred, bumpCycle does this.
    IsResourceLimited =
        checkResourceLimit(SchedModel->getLatencyFactor(), getCriticalCount(),
                           getScheduledLatency(), true);

  // Update CurrMOps after calling bumpCycle to handle stalls, since bumpCycle
  // resets CurrMOps. Loop to handle instructions with more MOps than issue in
  // one cycle.  Since we commonly reach the max MOps here, opportunistically
  // bump the cycle to avoid uselessly checking everything in the readyQ.
  CurrMOps += IncMOps;

  // Bump the cycle count for issue group constraints.
  // This must be done after NextCycle has been adjust for all other stalls.
  // Calling bumpCycle(X) will reduce CurrMOps by one issue group and set
  // currCycle to X.
  if ((isTop() &&  SchedModel->mustEndGroup(SU->getInstr())) ||
      (!isTop() && SchedModel->mustBeginGroup(SU->getInstr()))) {
    LLVM_DEBUG(dbgs() << "  Bump cycle to " << (isTop() ? "end" : "begin")
                      << " group\n");
    bumpCycle(++NextCycle);
  }

  while (CurrMOps >= SchedModel->getIssueWidth()) {
    LLVM_DEBUG(dbgs() << "  *** Max MOps " << CurrMOps << " at cycle "
                      << CurrCycle << '\n');
    bumpCycle(++NextCycle);
  }
  LLVM_DEBUG(dumpScheduledState());
}

/// Release pending ready nodes in to the available queue. This makes them
/// visible to heuristics.
void SchedBoundary::releasePending() {
  // If the available queue is empty, it is safe to reset MinReadyCycle.
  if (Available.empty())
    MinReadyCycle = std::numeric_limits<unsigned>::max();

  // Check to see if any of the pending instructions are ready to issue.  If
  // so, add them to the available queue.
  for (unsigned I = 0, E = Pending.size(); I < E; ++I) {
    SUnit *SU = *(Pending.begin() + I);
    unsigned ReadyCycle = isTop() ? SU->TopReadyCycle : SU->BotReadyCycle;

    LLVM_DEBUG(dbgs() << "Checking pending node SU(" << SU->NodeNum << ")\n");

    if (ReadyCycle < MinReadyCycle)
      MinReadyCycle = ReadyCycle;

    if (Available.size() >= ReadyListLimit)
      break;

    releaseNode(SU, ReadyCycle, true, I);
    if (E != Pending.size()) {
      --I;
      --E;
    }
  }
  CheckPending = false;
}

/// Remove SU from the ready set for this boundary.
void SchedBoundary::removeReady(SUnit *SU) {
  if (Available.isInQueue(SU))
    Available.remove(Available.find(SU));
  else {
    assert(Pending.isInQueue(SU) && "bad ready count");
    Pending.remove(Pending.find(SU));
  }
}

/// If this queue only has one ready candidate, return it. As a side effect,
/// defer any nodes that now hit a hazard, and advance the cycle until at least
/// one node is ready. If multiple instructions are ready, return NULL.
SUnit *SchedBoundary::pickOnlyChoice() {
  if (CheckPending)
    releasePending();

  // Defer any ready instrs that now have a hazard.
  for (ReadyQueue::iterator I = Available.begin(); I != Available.end();) {
    if (checkHazard(*I)) {
      Pending.push(*I);
      I = Available.remove(I);
      continue;
    }
    ++I;
  }
  for (unsigned i = 0; Available.empty(); ++i) {
//  FIXME: Re-enable assert once PR20057 is resolved.
//    assert(i <= (HazardRec->getMaxLookAhead() + MaxObservedStall) &&
//           "permanent hazard");
    (void)i;
    bumpCycle(CurrCycle + 1);
    releasePending();
  }

  LLVM_DEBUG(Pending.dump());
  LLVM_DEBUG(Available.dump());

  if (Available.size() == 1)
    return *Available.begin();
  return nullptr;
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

/// Dump the content of the \ref ReservedCycles vector for the
/// resources that are used in the basic block.
///
LLVM_DUMP_METHOD void SchedBoundary::dumpReservedCycles() const {
  if (!SchedModel->hasInstrSchedModel())
    return;

  unsigned ResourceCount = SchedModel->getNumProcResourceKinds();
  unsigned StartIdx = 0;

  for (unsigned ResIdx = 0; ResIdx < ResourceCount; ++ResIdx) {
    const unsigned NumUnits = SchedModel->getProcResource(ResIdx)->NumUnits;
    std::string ResName = SchedModel->getResourceName(ResIdx);
    for (unsigned UnitIdx = 0; UnitIdx < NumUnits; ++UnitIdx) {
      dbgs() << ResName << "(" << UnitIdx << ") = ";
      if (SchedModel && SchedModel->enableIntervals()) {
        if (ReservedResourceSegments.count(StartIdx + UnitIdx))
          dbgs() << ReservedResourceSegments.at(StartIdx + UnitIdx);
        else
          dbgs() << "{ }\n";
      } else
        dbgs() << ReservedCycles[StartIdx + UnitIdx] << "\n";
    }
    StartIdx += NumUnits;
  }
}

// This is useful information to dump after bumpNode.
// Note that the Queue contents are more useful before pickNodeFromQueue.
LLVM_DUMP_METHOD void SchedBoundary::dumpScheduledState() const {
  unsigned ResFactor;
  unsigned ResCount;
  if (ZoneCritResIdx) {
    ResFactor = SchedModel->getResourceFactor(ZoneCritResIdx);
    ResCount = getResourceCount(ZoneCritResIdx);
  } else {
    ResFactor = SchedModel->getMicroOpFactor();
    ResCount = RetiredMOps * ResFactor;
  }
  unsigned LFactor = SchedModel->getLatencyFactor();
  dbgs() << Available.getName() << " @" << CurrCycle << "c\n"
         << "  Retired: " << RetiredMOps;
  dbgs() << "\n  Executed: " << getExecutedCount() / LFactor << "c";
  dbgs() << "\n  Critical: " << ResCount / LFactor << "c, "
         << ResCount / ResFactor << " "
         << SchedModel->getResourceName(ZoneCritResIdx)
         << "\n  ExpectedLatency: " << ExpectedLatency << "c\n"
         << (IsResourceLimited ? "  - Resource" : "  - Latency")
         << " limited.\n";
  if (MISchedDumpReservedCycles)
    dumpReservedCycles();
}
#endif

//===----------------------------------------------------------------------===//
// GenericScheduler - Generic implementation of MachineSchedStrategy.
//===----------------------------------------------------------------------===//

void GenericSchedulerBase::SchedCandidate::
initResourceDelta(const ScheduleDAGMI *DAG,
                  const TargetSchedModel *SchedModel) {
  if (!Policy.ReduceResIdx && !Policy.DemandResIdx)
    return;

  const MCSchedClassDesc *SC = DAG->getSchedClass(SU);
  for (TargetSchedModel::ProcResIter
         PI = SchedModel->getWriteProcResBegin(SC),
         PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {
    if (PI->ProcResourceIdx == Policy.ReduceResIdx)
      ResDelta.CritResources += PI->ReleaseAtCycle;
    if (PI->ProcResourceIdx == Policy.DemandResIdx)
      ResDelta.DemandedResources += PI->ReleaseAtCycle;
  }
}

/// Compute remaining latency. We need this both to determine whether the
/// overall schedule has become latency-limited and whether the instructions
/// outside this zone are resource or latency limited.
///
/// The "dependent" latency is updated incrementally during scheduling as the
/// max height/depth of scheduled nodes minus the cycles since it was
/// scheduled:
///   DLat = max (N.depth - (CurrCycle - N.ReadyCycle) for N in Zone
///
/// The "independent" latency is the max ready queue depth:
///   ILat = max N.depth for N in Available|Pending
///
/// RemainingLatency is the greater of independent and dependent latency.
///
/// These computations are expensive, especially in DAGs with many edges, so
/// only do them if necessary.
static unsigned computeRemLatency(SchedBoundary &CurrZone) {
  unsigned RemLatency = CurrZone.getDependentLatency();
  RemLatency = std::max(RemLatency,
                        CurrZone.findMaxLatency(CurrZone.Available.elements()));
  RemLatency = std::max(RemLatency,
                        CurrZone.findMaxLatency(CurrZone.Pending.elements()));
  return RemLatency;
}

/// Returns true if the current cycle plus remaning latency is greater than
/// the critical path in the scheduling region.
bool GenericSchedulerBase::shouldReduceLatency(const CandPolicy &Policy,
                                               SchedBoundary &CurrZone,
                                               bool ComputeRemLatency,
                                               unsigned &RemLatency) const {
  // The current cycle is already greater than the critical path, so we are
  // already latency limited and don't need to compute the remaining latency.
  if (CurrZone.getCurrCycle() > Rem.CriticalPath)
    return true;

  // If we haven't scheduled anything yet, then we aren't latency limited.
  if (CurrZone.getCurrCycle() == 0)
    return false;

  if (ComputeRemLatency)
    RemLatency = computeRemLatency(CurrZone);

  return RemLatency + CurrZone.getCurrCycle() > Rem.CriticalPath;
}

/// Set the CandPolicy given a scheduling zone given the current resources and
/// latencies inside and outside the zone.
void GenericSchedulerBase::setPolicy(CandPolicy &Policy, bool IsPostRA,
                                     SchedBoundary &CurrZone,
                                     SchedBoundary *OtherZone) {
  // Apply preemptive heuristics based on the total latency and resources
  // inside and outside this zone. Potential stalls should be considered before
  // following this policy.

  // Compute the critical resource outside the zone.
  unsigned OtherCritIdx = 0;
  unsigned OtherCount =
    OtherZone ? OtherZone->getOtherResourceCount(OtherCritIdx) : 0;

  bool OtherResLimited = false;
  unsigned RemLatency = 0;
  bool RemLatencyComputed = false;
  if (SchedModel->hasInstrSchedModel() && OtherCount != 0) {
    RemLatency = computeRemLatency(CurrZone);
    RemLatencyComputed = true;
    OtherResLimited = checkResourceLimit(SchedModel->getLatencyFactor(),
                                         OtherCount, RemLatency, false);
  }

  // Schedule aggressively for latency in PostRA mode. We don't check for
  // acyclic latency during PostRA, and highly out-of-order processors will
  // skip PostRA scheduling.
  if (!OtherResLimited &&
      (IsPostRA || shouldReduceLatency(Policy, CurrZone, !RemLatencyComputed,
                                       RemLatency))) {
    Policy.ReduceLatency |= true;
    LLVM_DEBUG(dbgs() << "  " << CurrZone.Available.getName()
                      << " RemainingLatency " << RemLatency << " + "
                      << CurrZone.getCurrCycle() << "c > CritPath "
                      << Rem.CriticalPath << "\n");
  }
  // If the same resource is limiting inside and outside the zone, do nothing.
  if (CurrZone.getZoneCritResIdx() == OtherCritIdx)
    return;

  LLVM_DEBUG(if (CurrZone.isResourceLimited()) {
    dbgs() << "  " << CurrZone.Available.getName() << " ResourceLimited: "
           << SchedModel->getResourceName(CurrZone.getZoneCritResIdx()) << "\n";
  } if (OtherResLimited) dbgs()
                 << "  RemainingLimit: "
                 << SchedModel->getResourceName(OtherCritIdx) << "\n";
             if (!CurrZone.isResourceLimited() && !OtherResLimited) dbgs()
             << "  Latency limited both directions.\n");

  if (CurrZone.isResourceLimited() && !Policy.ReduceResIdx)
    Policy.ReduceResIdx = CurrZone.getZoneCritResIdx();

  if (OtherResLimited)
    Policy.DemandResIdx = OtherCritIdx;
}

#ifndef NDEBUG
const char *GenericSchedulerBase::getReasonStr(
  GenericSchedulerBase::CandReason Reason) {
  // clang-format off
  switch (Reason) {
  case NoCand:         return "NOCAND    ";
  case Only1:          return "ONLY1     ";
  case PhysReg:        return "PHYS-REG  ";
  case RegExcess:      return "REG-EXCESS";
  case RegCritical:    return "REG-CRIT  ";
  case Stall:          return "STALL     ";
  case Cluster:        return "CLUSTER   ";
  case Weak:           return "WEAK      ";
  case RegMax:         return "REG-MAX   ";
  case ResourceReduce: return "RES-REDUCE";
  case ResourceDemand: return "RES-DEMAND";
  case TopDepthReduce: return "TOP-DEPTH ";
  case TopPathReduce:  return "TOP-PATH  ";
  case BotHeightReduce:return "BOT-HEIGHT";
  case BotPathReduce:  return "BOT-PATH  ";
  case NodeOrder:      return "ORDER     ";
  case FirstValid:     return "FIRST     ";
  };
  // clang-format on
  llvm_unreachable("Unknown reason!");
}

void GenericSchedulerBase::traceCandidate(const SchedCandidate &Cand) {
  PressureChange P;
  unsigned ResIdx = 0;
  unsigned Latency = 0;
  switch (Cand.Reason) {
  default:
    break;
  case RegExcess:
    P = Cand.RPDelta.Excess;
    break;
  case RegCritical:
    P = Cand.RPDelta.CriticalMax;
    break;
  case RegMax:
    P = Cand.RPDelta.CurrentMax;
    break;
  case ResourceReduce:
    ResIdx = Cand.Policy.ReduceResIdx;
    break;
  case ResourceDemand:
    ResIdx = Cand.Policy.DemandResIdx;
    break;
  case TopDepthReduce:
    Latency = Cand.SU->getDepth();
    break;
  case TopPathReduce:
    Latency = Cand.SU->getHeight();
    break;
  case BotHeightReduce:
    Latency = Cand.SU->getHeight();
    break;
  case BotPathReduce:
    Latency = Cand.SU->getDepth();
    break;
  }
  dbgs() << "  Cand SU(" << Cand.SU->NodeNum << ") " << getReasonStr(Cand.Reason);
  if (P.isValid())
    dbgs() << " " << TRI->getRegPressureSetName(P.getPSet())
           << ":" << P.getUnitInc() << " ";
  else
    dbgs() << "      ";
  if (ResIdx)
    dbgs() << " " << SchedModel->getProcResource(ResIdx)->Name << " ";
  else
    dbgs() << "         ";
  if (Latency)
    dbgs() << " " << Latency << " cycles ";
  else
    dbgs() << "          ";
  dbgs() << '\n';
}
#endif

namespace llvm {
/// Return true if this heuristic determines order.
/// TODO: Consider refactor return type of these functions as integer or enum,
/// as we may need to differentiate whether TryCand is better than Cand.
bool tryLess(int TryVal, int CandVal,
             GenericSchedulerBase::SchedCandidate &TryCand,
             GenericSchedulerBase::SchedCandidate &Cand,
             GenericSchedulerBase::CandReason Reason) {
  if (TryVal < CandVal) {
    TryCand.Reason = Reason;
    return true;
  }
  if (TryVal > CandVal) {
    if (Cand.Reason > Reason)
      Cand.Reason = Reason;
    return true;
  }
  return false;
}

bool tryGreater(int TryVal, int CandVal,
                GenericSchedulerBase::SchedCandidate &TryCand,
                GenericSchedulerBase::SchedCandidate &Cand,
                GenericSchedulerBase::CandReason Reason) {
  if (TryVal > CandVal) {
    TryCand.Reason = Reason;
    return true;
  }
  if (TryVal < CandVal) {
    if (Cand.Reason > Reason)
      Cand.Reason = Reason;
    return true;
  }
  return false;
}

bool tryLatency(GenericSchedulerBase::SchedCandidate &TryCand,
                GenericSchedulerBase::SchedCandidate &Cand,
                SchedBoundary &Zone) {
  if (Zone.isTop()) {
    // Prefer the candidate with the lesser depth, but only if one of them has
    // depth greater than the total latency scheduled so far, otherwise either
    // of them could be scheduled now with no stall.
    if (std::max(TryCand.SU->getDepth(), Cand.SU->getDepth()) >
        Zone.getScheduledLatency()) {
      if (tryLess(TryCand.SU->getDepth(), Cand.SU->getDepth(),
                  TryCand, Cand, GenericSchedulerBase::TopDepthReduce))
        return true;
    }
    if (tryGreater(TryCand.SU->getHeight(), Cand.SU->getHeight(),
                   TryCand, Cand, GenericSchedulerBase::TopPathReduce))
      return true;
  } else {
    // Prefer the candidate with the lesser height, but only if one of them has
    // height greater than the total latency scheduled so far, otherwise either
    // of them could be scheduled now with no stall.
    if (std::max(TryCand.SU->getHeight(), Cand.SU->getHeight()) >
        Zone.getScheduledLatency()) {
      if (tryLess(TryCand.SU->getHeight(), Cand.SU->getHeight(),
                  TryCand, Cand, GenericSchedulerBase::BotHeightReduce))
        return true;
    }
    if (tryGreater(TryCand.SU->getDepth(), Cand.SU->getDepth(),
                   TryCand, Cand, GenericSchedulerBase::BotPathReduce))
      return true;
  }
  return false;
}
} // end namespace llvm

static void tracePick(GenericSchedulerBase::CandReason Reason, bool IsTop,
                      bool IsPostRA = false) {
  LLVM_DEBUG(dbgs() << "Pick " << (IsTop ? "Top " : "Bot ")
                    << GenericSchedulerBase::getReasonStr(Reason) << " ["
                    << (IsPostRA ? "post-RA" : "pre-RA") << "]\n");

  if (IsPostRA) {
    if (IsTop)
      NumTopPostRA++;
    else
      NumBotPostRA++;

    switch (Reason) {
    case GenericScheduler::NoCand:
      NumNoCandPostRA++;
      return;
    case GenericScheduler::Only1:
      NumOnly1PostRA++;
      return;
    case GenericScheduler::PhysReg:
      NumPhysRegPostRA++;
      return;
    case GenericScheduler::RegExcess:
      NumRegExcessPostRA++;
      return;
    case GenericScheduler::RegCritical:
      NumRegCriticalPostRA++;
      return;
    case GenericScheduler::Stall:
      NumStallPostRA++;
      return;
    case GenericScheduler::Cluster:
      NumClusterPostRA++;
      return;
    case GenericScheduler::Weak:
      NumWeakPostRA++;
      return;
    case GenericScheduler::RegMax:
      NumRegMaxPostRA++;
      return;
    case GenericScheduler::ResourceReduce:
      NumResourceReducePostRA++;
      return;
    case GenericScheduler::ResourceDemand:
      NumResourceDemandPostRA++;
      return;
    case GenericScheduler::TopDepthReduce:
      NumTopDepthReducePostRA++;
      return;
    case GenericScheduler::TopPathReduce:
      NumTopPathReducePostRA++;
      return;
    case GenericScheduler::BotHeightReduce:
      NumBotHeightReducePostRA++;
      return;
    case GenericScheduler::BotPathReduce:
      NumBotPathReducePostRA++;
      return;
    case GenericScheduler::NodeOrder:
      NumNodeOrderPostRA++;
      return;
    case GenericScheduler::FirstValid:
      NumFirstValidPostRA++;
      return;
    };
  } else {
    if (IsTop)
      NumTopPreRA++;
    else
      NumBotPreRA++;

    switch (Reason) {
    case GenericScheduler::NoCand:
      NumNoCandPreRA++;
      return;
    case GenericScheduler::Only1:
      NumOnly1PreRA++;
      return;
    case GenericScheduler::PhysReg:
      NumPhysRegPreRA++;
      return;
    case GenericScheduler::RegExcess:
      NumRegExcessPreRA++;
      return;
    case GenericScheduler::RegCritical:
      NumRegCriticalPreRA++;
      return;
    case GenericScheduler::Stall:
      NumStallPreRA++;
      return;
    case GenericScheduler::Cluster:
      NumClusterPreRA++;
      return;
    case GenericScheduler::Weak:
      NumWeakPreRA++;
      return;
    case GenericScheduler::RegMax:
      NumRegMaxPreRA++;
      return;
    case GenericScheduler::ResourceReduce:
      NumResourceReducePreRA++;
      return;
    case GenericScheduler::ResourceDemand:
      NumResourceDemandPreRA++;
      return;
    case GenericScheduler::TopDepthReduce:
      NumTopDepthReducePreRA++;
      return;
    case GenericScheduler::TopPathReduce:
      NumTopPathReducePreRA++;
      return;
    case GenericScheduler::BotHeightReduce:
      NumBotHeightReducePreRA++;
      return;
    case GenericScheduler::BotPathReduce:
      NumBotPathReducePreRA++;
      return;
    case GenericScheduler::NodeOrder:
      NumNodeOrderPreRA++;
      return;
    case GenericScheduler::FirstValid:
      NumFirstValidPreRA++;
      return;
    };
  }
  llvm_unreachable("Unknown reason!");
}

static void tracePick(const GenericSchedulerBase::SchedCandidate &Cand,
                      bool IsPostRA = false) {
  tracePick(Cand.Reason, Cand.AtTop, IsPostRA);
}

void GenericScheduler::initialize(ScheduleDAGMI *dag) {
  assert(dag->hasVRegLiveness() &&
         "(PreRA)GenericScheduler needs vreg liveness");
  DAG = static_cast<ScheduleDAGMILive*>(dag);
  SchedModel = DAG->getSchedModel();
  TRI = DAG->TRI;

  if (RegionPolicy.ComputeDFSResult)
    DAG->computeDFSResult();

  Rem.init(DAG, SchedModel);
  Top.init(DAG, SchedModel, &Rem);
  Bot.init(DAG, SchedModel, &Rem);

  // Initialize resource counts.

  // Initialize the HazardRecognizers. If itineraries don't exist, are empty, or
  // are disabled, then these HazardRecs will be disabled.
  const InstrItineraryData *Itin = SchedModel->getInstrItineraries();
  if (!Top.HazardRec) {
    Top.HazardRec = DAG->TII->CreateTargetMIHazardRecognizer(Itin, DAG);
  }
  if (!Bot.HazardRec) {
    Bot.HazardRec = DAG->TII->CreateTargetMIHazardRecognizer(Itin, DAG);
  }
  TopCand.SU = nullptr;
  BotCand.SU = nullptr;

  TopClusterID = InvalidClusterId;
  BotClusterID = InvalidClusterId;
}

/// Initialize the per-region scheduling policy.
void GenericScheduler::initPolicy(MachineBasicBlock::iterator Begin,
                                  MachineBasicBlock::iterator End,
                                  unsigned NumRegionInstrs) {
  const MachineFunction &MF = *Begin->getMF();
  const TargetLowering *TLI = MF.getSubtarget().getTargetLowering();

  // Avoid setting up the register pressure tracker for small regions to save
  // compile time. As a rough heuristic, only track pressure when the number of
  // schedulable instructions exceeds half the allocatable integer register file
  // that is the largest legal integer regiser type.
  RegionPolicy.ShouldTrackPressure = true;
  for (unsigned VT = MVT::i64; VT > (unsigned)MVT::i1; --VT) {
    MVT::SimpleValueType LegalIntVT = (MVT::SimpleValueType)VT;
    if (TLI->isTypeLegal(LegalIntVT)) {
      unsigned NIntRegs = Context->RegClassInfo->getNumAllocatableRegs(
        TLI->getRegClassFor(LegalIntVT));
      RegionPolicy.ShouldTrackPressure = NumRegionInstrs > (NIntRegs / 2);
      break;
    }
  }

  // For generic targets, we default to bottom-up, because it's simpler and more
  // compile-time optimizations have been implemented in that direction.
  RegionPolicy.OnlyBottomUp = true;

  // Allow the subtarget to override default policy.
  SchedRegion Region(Begin, End, NumRegionInstrs);
  MF.getSubtarget().overrideSchedPolicy(RegionPolicy, Region);

  // After subtarget overrides, apply command line options.
  if (!EnableRegPressure) {
    RegionPolicy.ShouldTrackPressure = false;
    RegionPolicy.ShouldTrackLaneMasks = false;
  }

  if (PreRADirection == MISched::TopDown) {
    RegionPolicy.OnlyTopDown = true;
    RegionPolicy.OnlyBottomUp = false;
  } else if (PreRADirection == MISched::BottomUp) {
    RegionPolicy.OnlyTopDown = false;
    RegionPolicy.OnlyBottomUp = true;
  } else if (PreRADirection == MISched::Bidirectional) {
    RegionPolicy.OnlyBottomUp = false;
    RegionPolicy.OnlyTopDown = false;
  }

  BotIdx = NumRegionInstrs - 1;
  this->NumRegionInstrs = NumRegionInstrs;
}

void GenericScheduler::dumpPolicy() const {
  // Cannot completely remove virtual function even in release mode.
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  dbgs() << "GenericScheduler RegionPolicy: "
         << " ShouldTrackPressure=" << RegionPolicy.ShouldTrackPressure
         << " OnlyTopDown=" << RegionPolicy.OnlyTopDown
         << " OnlyBottomUp=" << RegionPolicy.OnlyBottomUp
         << "\n";
#endif
}

/// Set IsAcyclicLatencyLimited if the acyclic path is longer than the cyclic
/// critical path by more cycles than it takes to drain the instruction buffer.
/// We estimate an upper bounds on in-flight instructions as:
///
/// CyclesPerIteration = max( CyclicPath, Loop-Resource-Height )
/// InFlightIterations = AcyclicPath / CyclesPerIteration
/// InFlightResources = InFlightIterations * LoopResources
///
/// TODO: Check execution resources in addition to IssueCount.
void GenericScheduler::checkAcyclicLatency() {
  if (Rem.CyclicCritPath == 0 || Rem.CyclicCritPath >= Rem.CriticalPath)
    return;

  // Scaled number of cycles per loop iteration.
  unsigned IterCount =
    std::max(Rem.CyclicCritPath * SchedModel->getLatencyFactor(),
             Rem.RemIssueCount);
  // Scaled acyclic critical path.
  unsigned AcyclicCount = Rem.CriticalPath * SchedModel->getLatencyFactor();
  // InFlightCount = (AcyclicPath / IterCycles) * InstrPerLoop
  unsigned InFlightCount =
    (AcyclicCount * Rem.RemIssueCount + IterCount-1) / IterCount;
  unsigned BufferLimit =
    SchedModel->getMicroOpBufferSize() * SchedModel->getMicroOpFactor();

  Rem.IsAcyclicLatencyLimited = InFlightCount > BufferLimit;

  LLVM_DEBUG(
      dbgs() << "IssueCycles="
             << Rem.RemIssueCount / SchedModel->getLatencyFactor() << "c "
             << "IterCycles=" << IterCount / SchedModel->getLatencyFactor()
             << "c NumIters=" << (AcyclicCount + IterCount - 1) / IterCount
             << " InFlight=" << InFlightCount / SchedModel->getMicroOpFactor()
             << "m BufferLim=" << SchedModel->getMicroOpBufferSize() << "m\n";
      if (Rem.IsAcyclicLatencyLimited) dbgs() << "  ACYCLIC LATENCY LIMIT\n");
}

void GenericScheduler::registerRoots() {
  Rem.CriticalPath = DAG->ExitSU.getDepth();

  // Some roots may not feed into ExitSU. Check all of them in case.
  for (const SUnit *SU : Bot.Available) {
    if (SU->getDepth() > Rem.CriticalPath)
      Rem.CriticalPath = SU->getDepth();
  }
  LLVM_DEBUG(dbgs() << "Critical Path(GS-RR ): " << Rem.CriticalPath << '\n');
  if (DumpCriticalPathLength) {
    errs() << "Critical Path(GS-RR ): " << Rem.CriticalPath << " \n";
  }

  if (EnableCyclicPath && SchedModel->getMicroOpBufferSize() > 0) {
    Rem.CyclicCritPath = DAG->computeCyclicCriticalPath();
    checkAcyclicLatency();
  }
}

namespace llvm {
bool tryPressure(const PressureChange &TryP,
                 const PressureChange &CandP,
                 GenericSchedulerBase::SchedCandidate &TryCand,
                 GenericSchedulerBase::SchedCandidate &Cand,
                 GenericSchedulerBase::CandReason Reason,
                 const TargetRegisterInfo *TRI,
                 const MachineFunction &MF) {
  // If one candidate decreases and the other increases, go with it.
  // Invalid candidates have UnitInc==0.
  if (tryGreater(TryP.getUnitInc() < 0, CandP.getUnitInc() < 0, TryCand, Cand,
                 Reason)) {
    return true;
  }
  // Do not compare the magnitude of pressure changes between top and bottom
  // boundary.
  if (Cand.AtTop != TryCand.AtTop)
    return false;

  // If both candidates affect the same set in the same boundary, go with the
  // smallest increase.
  unsigned TryPSet = TryP.getPSetOrMax();
  unsigned CandPSet = CandP.getPSetOrMax();
  if (TryPSet == CandPSet) {
    return tryLess(TryP.getUnitInc(), CandP.getUnitInc(), TryCand, Cand,
                   Reason);
  }

  int TryRank = TryP.isValid() ? TRI->getRegPressureSetScore(MF, TryPSet) :
                                 std::numeric_limits<int>::max();

  int CandRank = CandP.isValid() ? TRI->getRegPressureSetScore(MF, CandPSet) :
                                   std::numeric_limits<int>::max();

  // If the candidates are decreasing pressure, reverse priority.
  if (TryP.getUnitInc() < 0)
    std::swap(TryRank, CandRank);
  return tryGreater(TryRank, CandRank, TryCand, Cand, Reason);
}

unsigned getWeakLeft(const SUnit *SU, bool isTop) {
  return (isTop) ? SU->WeakPredsLeft : SU->WeakSuccsLeft;
}

/// Minimize physical register live ranges. Regalloc wants them adjacent to
/// their physreg def/use.
///
/// FIXME: This is an unnecessary check on the critical path. Most are root/leaf
/// copies which can be prescheduled. The rest (e.g. x86 MUL) could be bundled
/// with the operation that produces or consumes the physreg. We'll do this when
/// regalloc has support for parallel copies.
int biasPhysReg(const SUnit *SU, bool isTop) {
  const MachineInstr *MI = SU->getInstr();

  if (MI->isCopy()) {
    unsigned ScheduledOper = isTop ? 1 : 0;
    unsigned UnscheduledOper = isTop ? 0 : 1;
    // If we have already scheduled the physreg produce/consumer, immediately
    // schedule the copy.
    if (MI->getOperand(ScheduledOper).getReg().isPhysical())
      return 1;
    // If the physreg is at the boundary, defer it. Otherwise schedule it
    // immediately to free the dependent. We can hoist the copy later.
    bool AtBoundary = isTop ? !SU->NumSuccsLeft : !SU->NumPredsLeft;
    if (MI->getOperand(UnscheduledOper).getReg().isPhysical())
      return AtBoundary ? -1 : 1;
  }

  if (MI->isMoveImmediate()) {
    // If we have a move immediate and all successors have been assigned, bias
    // towards scheduling this later. Make sure all register defs are to
    // physical registers.
    bool DoBias = true;
    for (const MachineOperand &Op : MI->defs()) {
      if (Op.isReg() && !Op.getReg().isPhysical()) {
        DoBias = false;
        break;
      }
    }

    if (DoBias)
      return isTop ? -1 : 1;
  }

  return 0;
}
} // end namespace llvm

void GenericScheduler::initCandidate(SchedCandidate &Cand, SUnit *SU,
                                     bool AtTop,
                                     const RegPressureTracker &RPTracker,
                                     RegPressureTracker &TempTracker) {
  Cand.SU = SU;
  Cand.AtTop = AtTop;
  if (DAG->isTrackingPressure()) {
    if (AtTop) {
      TempTracker.getMaxDownwardPressureDelta(
        Cand.SU->getInstr(),
        Cand.RPDelta,
        DAG->getRegionCriticalPSets(),
        DAG->getRegPressure().MaxSetPressure);
    } else {
      if (VerifyScheduling) {
        TempTracker.getMaxUpwardPressureDelta(
          Cand.SU->getInstr(),
          &DAG->getPressureDiff(Cand.SU),
          Cand.RPDelta,
          DAG->getRegionCriticalPSets(),
          DAG->getRegPressure().MaxSetPressure);
      } else {
        RPTracker.getUpwardPressureDelta(
          Cand.SU->getInstr(),
          DAG->getPressureDiff(Cand.SU),
          Cand.RPDelta,
          DAG->getRegionCriticalPSets(),
          DAG->getRegPressure().MaxSetPressure);
      }
    }
  }
  LLVM_DEBUG(if (Cand.RPDelta.Excess.isValid()) dbgs()
             << "  Try  SU(" << Cand.SU->NodeNum << ") "
             << TRI->getRegPressureSetName(Cand.RPDelta.Excess.getPSet()) << ":"
             << Cand.RPDelta.Excess.getUnitInc() << "\n");
}

/// Apply a set of heuristics to a new candidate. Heuristics are currently
/// hierarchical. This may be more efficient than a graduated cost model because
/// we don't need to evaluate all aspects of the model for each node in the
/// queue. But it's really done to make the heuristics easier to debug and
/// statistically analyze.
///
/// \param Cand provides the policy and current best candidate.
/// \param TryCand refers to the next SUnit candidate, otherwise uninitialized.
/// \param Zone describes the scheduled zone that we are extending, or nullptr
///             if Cand is from a different zone than TryCand.
/// \return \c true if TryCand is better than Cand (Reason is NOT NoCand)
bool GenericScheduler::tryCandidate(SchedCandidate &Cand,
                                    SchedCandidate &TryCand,
                                    SchedBoundary *Zone) const {
  // Initialize the candidate if needed.
  if (!Cand.isValid()) {
    TryCand.Reason = FirstValid;
    return true;
  }

  // Bias PhysReg Defs and copies to their uses and defined respectively.
  if (tryGreater(biasPhysReg(TryCand.SU, TryCand.AtTop),
                 biasPhysReg(Cand.SU, Cand.AtTop), TryCand, Cand, PhysReg))
    return TryCand.Reason != NoCand;

  // Avoid exceeding the target's limit.
  if (DAG->isTrackingPressure() && tryPressure(TryCand.RPDelta.Excess,
                                               Cand.RPDelta.Excess,
                                               TryCand, Cand, RegExcess, TRI,
                                               DAG->MF))
    return TryCand.Reason != NoCand;

  // Avoid increasing the max critical pressure in the scheduled region.
  if (DAG->isTrackingPressure() && tryPressure(TryCand.RPDelta.CriticalMax,
                                               Cand.RPDelta.CriticalMax,
                                               TryCand, Cand, RegCritical, TRI,
                                               DAG->MF))
    return TryCand.Reason != NoCand;

  // We only compare a subset of features when comparing nodes between
  // Top and Bottom boundary. Some properties are simply incomparable, in many
  // other instances we should only override the other boundary if something
  // is a clear good pick on one boundary. Skip heuristics that are more
  // "tie-breaking" in nature.
  bool SameBoundary = Zone != nullptr;
  if (SameBoundary) {
    // For loops that are acyclic path limited, aggressively schedule for
    // latency. Within an single cycle, whenever CurrMOps > 0, allow normal
    // heuristics to take precedence.
    if (Rem.IsAcyclicLatencyLimited && !Zone->getCurrMOps() &&
        tryLatency(TryCand, Cand, *Zone))
      return TryCand.Reason != NoCand;

    // Prioritize instructions that read unbuffered resources by stall cycles.
    if (tryLess(Zone->getLatencyStallCycles(TryCand.SU),
                Zone->getLatencyStallCycles(Cand.SU), TryCand, Cand, Stall))
      return TryCand.Reason != NoCand;
  }

  // Keep clustered nodes together to encourage downstream peephole
  // optimizations which may reduce resource requirements.
  //
  // This is a best effort to set things up for a post-RA pass. Optimizations
  // like generating loads of multiple registers should ideally be done within
  // the scheduler pass by combining the loads during DAG postprocessing.
  unsigned CandZoneCluster = Cand.AtTop ? TopClusterID : BotClusterID;
  unsigned TryCandZoneCluster = TryCand.AtTop ? TopClusterID : BotClusterID;
  bool CandIsClusterSucc =
      isTheSameCluster(CandZoneCluster, Cand.SU->ParentClusterIdx);
  bool TryCandIsClusterSucc =
      isTheSameCluster(TryCandZoneCluster, TryCand.SU->ParentClusterIdx);

  if (tryGreater(TryCandIsClusterSucc, CandIsClusterSucc, TryCand, Cand,
                 Cluster))
    return TryCand.Reason != NoCand;

  if (SameBoundary) {
    // Weak edges are for clustering and other constraints.
    if (tryLess(getWeakLeft(TryCand.SU, TryCand.AtTop),
                getWeakLeft(Cand.SU, Cand.AtTop),
                TryCand, Cand, Weak))
      return TryCand.Reason != NoCand;
  }

  // Avoid increasing the max pressure of the entire region.
  if (DAG->isTrackingPressure() && tryPressure(TryCand.RPDelta.CurrentMax,
                                               Cand.RPDelta.CurrentMax,
                                               TryCand, Cand, RegMax, TRI,
                                               DAG->MF))
    return TryCand.Reason != NoCand;

  if (SameBoundary) {
    // Avoid critical resource consumption and balance the schedule.
    TryCand.initResourceDelta(DAG, SchedModel);
    if (tryLess(TryCand.ResDelta.CritResources, Cand.ResDelta.CritResources,
                TryCand, Cand, ResourceReduce))
      return TryCand.Reason != NoCand;
    if (tryGreater(TryCand.ResDelta.DemandedResources,
                   Cand.ResDelta.DemandedResources,
                   TryCand, Cand, ResourceDemand))
      return TryCand.Reason != NoCand;

    // Avoid serializing long latency dependence chains.
    // For acyclic path limited loops, latency was already checked above.
    if (!RegionPolicy.DisableLatencyHeuristic && TryCand.Policy.ReduceLatency &&
        !Rem.IsAcyclicLatencyLimited && tryLatency(TryCand, Cand, *Zone))
      return TryCand.Reason != NoCand;

    // Fall through to original instruction order.
    if ((Zone->isTop() && TryCand.SU->NodeNum < Cand.SU->NodeNum)
        || (!Zone->isTop() && TryCand.SU->NodeNum > Cand.SU->NodeNum)) {
      TryCand.Reason = NodeOrder;
      return true;
    }
  }

  return false;
}

/// Pick the best candidate from the queue.
///
/// TODO: getMaxPressureDelta results can be mostly cached for each SUnit during
/// DAG building. To adjust for the current scheduling location we need to
/// maintain the number of vreg uses remaining to be top-scheduled.
void GenericScheduler::pickNodeFromQueue(SchedBoundary &Zone,
                                         const CandPolicy &ZonePolicy,
                                         const RegPressureTracker &RPTracker,
                                         SchedCandidate &Cand) {
  // getMaxPressureDelta temporarily modifies the tracker.
  RegPressureTracker &TempTracker = const_cast<RegPressureTracker&>(RPTracker);

  ReadyQueue &Q = Zone.Available;
  for (SUnit *SU : Q) {

    SchedCandidate TryCand(ZonePolicy);
    initCandidate(TryCand, SU, Zone.isTop(), RPTracker, TempTracker);
    // Pass SchedBoundary only when comparing nodes from the same boundary.
    SchedBoundary *ZoneArg = Cand.AtTop == TryCand.AtTop ? &Zone : nullptr;
    if (tryCandidate(Cand, TryCand, ZoneArg)) {
      // Initialize resource delta if needed in case future heuristics query it.
      if (TryCand.ResDelta == SchedResourceDelta())
        TryCand.initResourceDelta(DAG, SchedModel);
      Cand.setBest(TryCand);
      LLVM_DEBUG(traceCandidate(Cand));
    }
  }
}

/// Pick the best candidate node from either the top or bottom queue.
SUnit *GenericScheduler::pickNodeBidirectional(bool &IsTopNode) {
  // Schedule as far as possible in the direction of no choice. This is most
  // efficient, but also provides the best heuristics for CriticalPSets.
  if (SUnit *SU = Bot.pickOnlyChoice()) {
    IsTopNode = false;
    tracePick(Only1, /*IsTopNode=*/false);
    return SU;
  }
  if (SUnit *SU = Top.pickOnlyChoice()) {
    IsTopNode = true;
    tracePick(Only1, /*IsTopNode=*/true);
    return SU;
  }
  // Set the bottom-up policy based on the state of the current bottom zone and
  // the instructions outside the zone, including the top zone.
  CandPolicy BotPolicy;
  setPolicy(BotPolicy, /*IsPostRA=*/false, Bot, &Top);
  // Set the top-down policy based on the state of the current top zone and
  // the instructions outside the zone, including the bottom zone.
  CandPolicy TopPolicy;
  setPolicy(TopPolicy, /*IsPostRA=*/false, Top, &Bot);

  // See if BotCand is still valid (because we previously scheduled from Top).
  LLVM_DEBUG(dbgs() << "Picking from Bot:\n");
  if (!BotCand.isValid() || BotCand.SU->isScheduled ||
      BotCand.Policy != BotPolicy) {
    BotCand.reset(CandPolicy());
    pickNodeFromQueue(Bot, BotPolicy, DAG->getBotRPTracker(), BotCand);
    assert(BotCand.Reason != NoCand && "failed to find the first candidate");
  } else {
    LLVM_DEBUG(traceCandidate(BotCand));
#ifndef NDEBUG
    if (VerifyScheduling) {
      SchedCandidate TCand;
      TCand.reset(CandPolicy());
      pickNodeFromQueue(Bot, BotPolicy, DAG->getBotRPTracker(), TCand);
      assert(TCand.SU == BotCand.SU &&
             "Last pick result should correspond to re-picking right now");
    }
#endif
  }

  // Check if the top Q has a better candidate.
  LLVM_DEBUG(dbgs() << "Picking from Top:\n");
  if (!TopCand.isValid() || TopCand.SU->isScheduled ||
      TopCand.Policy != TopPolicy) {
    TopCand.reset(CandPolicy());
    pickNodeFromQueue(Top, TopPolicy, DAG->getTopRPTracker(), TopCand);
    assert(TopCand.Reason != NoCand && "failed to find the first candidate");
  } else {
    LLVM_DEBUG(traceCandidate(TopCand));
#ifndef NDEBUG
    if (VerifyScheduling) {
      SchedCandidate TCand;
      TCand.reset(CandPolicy());
      pickNodeFromQueue(Top, TopPolicy, DAG->getTopRPTracker(), TCand);
      assert(TCand.SU == TopCand.SU &&
             "Last pick result should correspond to re-picking right now");
    }
#endif
  }

  // Pick best from BotCand and TopCand.
  assert(BotCand.isValid());
  assert(TopCand.isValid());
  SchedCandidate Cand = BotCand;
  TopCand.Reason = NoCand;
  if (tryCandidate(Cand, TopCand, nullptr)) {
    Cand.setBest(TopCand);
    LLVM_DEBUG(traceCandidate(Cand));
  }

  IsTopNode = Cand.AtTop;
  tracePick(Cand);
  return Cand.SU;
}

/// Pick the best node to balance the schedule. Implements MachineSchedStrategy.
SUnit *GenericScheduler::pickNode(bool &IsTopNode) {
  if (DAG->top() == DAG->bottom()) {
    assert(Top.Available.empty() && Top.Pending.empty() &&
           Bot.Available.empty() && Bot.Pending.empty() && "ReadyQ garbage");
    return nullptr;
  }
  SUnit *SU;
  do {
    if (RegionPolicy.OnlyTopDown) {
      SU = Top.pickOnlyChoice();
      if (!SU) {
        CandPolicy NoPolicy;
        TopCand.reset(NoPolicy);
        pickNodeFromQueue(Top, NoPolicy, DAG->getTopRPTracker(), TopCand);
        assert(TopCand.Reason != NoCand && "failed to find a candidate");
        tracePick(TopCand);
        SU = TopCand.SU;
      }
      IsTopNode = true;
    } else if (RegionPolicy.OnlyBottomUp) {
      SU = Bot.pickOnlyChoice();
      if (!SU) {
        CandPolicy NoPolicy;
        BotCand.reset(NoPolicy);
        pickNodeFromQueue(Bot, NoPolicy, DAG->getBotRPTracker(), BotCand);
        assert(BotCand.Reason != NoCand && "failed to find a candidate");
        tracePick(BotCand);
        SU = BotCand.SU;
      }
      IsTopNode = false;
    } else {
      SU = pickNodeBidirectional(IsTopNode);
    }
  } while (SU->isScheduled);

  // If IsTopNode, then SU is in Top.Available and must be removed. Otherwise,
  // if isTopReady(), then SU is in either Top.Available or Top.Pending.
  // If !IsTopNode, then SU is in Bot.Available and must be removed. Otherwise,
  // if isBottomReady(), then SU is in either Bot.Available or Bot.Pending.
  //
  // It is coincidental when !IsTopNode && isTopReady or when IsTopNode &&
  // isBottomReady. That is, it didn't factor into the decision to choose SU
  // because it isTopReady or isBottomReady, respectively. In fact, if the
  // RegionPolicy is OnlyTopDown or OnlyBottomUp, then the Bot queues and Top
  // queues respectivley contain the original roots and don't get updated when
  // picking a node. So if SU isTopReady on a OnlyBottomUp pick, then it was
  // because we schduled everything but the top roots. Conversley, if SU
  // isBottomReady on OnlyTopDown, then it was because we scheduled everything
  // but the bottom roots. If its in a queue even coincidentally, it should be
  // removed so it does not get re-picked in a subsequent pickNode call.
  if (SU->isTopReady())
    Top.removeReady(SU);
  if (SU->isBottomReady())
    Bot.removeReady(SU);

  LLVM_DEBUG(dbgs() << "Scheduling SU(" << SU->NodeNum << ") "
                    << *SU->getInstr());

  if (IsTopNode) {
    if (SU->NodeNum == TopIdx++)
      ++NumInstrsInSourceOrderPreRA;
  } else {
    assert(BotIdx < NumRegionInstrs && "out of bounds");
    if (SU->NodeNum == BotIdx--)
      ++NumInstrsInSourceOrderPreRA;
  }

  NumInstrsScheduledPreRA += 1;

  return SU;
}

void GenericScheduler::reschedulePhysReg(SUnit *SU, bool isTop) {
  MachineBasicBlock::iterator InsertPos = SU->getInstr();
  if (!isTop)
    ++InsertPos;
  SmallVectorImpl<SDep> &Deps = isTop ? SU->Preds : SU->Succs;

  // Find already scheduled copies with a single physreg dependence and move
  // them just above the scheduled instruction.
  for (SDep &Dep : Deps) {
    if (Dep.getKind() != SDep::Data || !Dep.getReg().isPhysical())
      continue;
    SUnit *DepSU = Dep.getSUnit();
    if (isTop ? DepSU->Succs.size() > 1 : DepSU->Preds.size() > 1)
      continue;
    MachineInstr *Copy = DepSU->getInstr();
    if (!Copy->isCopy() && !Copy->isMoveImmediate())
      continue;
    LLVM_DEBUG(dbgs() << "  Rescheduling physreg copy ";
               DAG->dumpNode(*Dep.getSUnit()));
    DAG->moveInstruction(Copy, InsertPos);
  }
}

/// Update the scheduler's state after scheduling a node. This is the same node
/// that was just returned by pickNode(). However, ScheduleDAGMILive needs to
/// update it's state based on the current cycle before MachineSchedStrategy
/// does.
///
/// FIXME: Eventually, we may bundle physreg copies rather than rescheduling
/// them here. See comments in biasPhysReg.
void GenericScheduler::schedNode(SUnit *SU, bool IsTopNode) {
  if (IsTopNode) {
    SU->TopReadyCycle = std::max(SU->TopReadyCycle, Top.getCurrCycle());
    TopClusterID = SU->ParentClusterIdx;
    LLVM_DEBUG({
      if (TopClusterID != InvalidClusterId) {
        ClusterInfo *TopCluster = DAG->getCluster(TopClusterID);
        dbgs() << "  Top Cluster: ";
        for (auto *N : *TopCluster)
          dbgs() << N->NodeNum << '\t';
        dbgs() << '\n';
      }
    });
    Top.bumpNode(SU);
    if (SU->hasPhysRegUses)
      reschedulePhysReg(SU, true);
  } else {
    SU->BotReadyCycle = std::max(SU->BotReadyCycle, Bot.getCurrCycle());
    BotClusterID = SU->ParentClusterIdx;
    LLVM_DEBUG({
      if (BotClusterID != InvalidClusterId) {
        ClusterInfo *BotCluster = DAG->getCluster(BotClusterID);
        dbgs() << "  Bot Cluster: ";
        for (auto *N : *BotCluster)
          dbgs() << N->NodeNum << '\t';
        dbgs() << '\n';
      }
    });
    Bot.bumpNode(SU);
    if (SU->hasPhysRegDefs)
      reschedulePhysReg(SU, false);
  }
}

static ScheduleDAGInstrs *createConvergingSched(MachineSchedContext *C) {
  return createSchedLive(C);
}

static MachineSchedRegistry
GenericSchedRegistry("converge", "Standard converging scheduler.",
                     createConvergingSched);

//===----------------------------------------------------------------------===//
// PostGenericScheduler - Generic PostRA implementation of MachineSchedStrategy.
//===----------------------------------------------------------------------===//

void PostGenericScheduler::initialize(ScheduleDAGMI *Dag) {
  DAG = Dag;
  SchedModel = DAG->getSchedModel();
  TRI = DAG->TRI;

  Rem.init(DAG, SchedModel);
  Top.init(DAG, SchedModel, &Rem);
  Bot.init(DAG, SchedModel, &Rem);

  // Initialize the HazardRecognizers. If itineraries don't exist, are empty,
  // or are disabled, then these HazardRecs will be disabled.
  const InstrItineraryData *Itin = SchedModel->getInstrItineraries();
  if (!Top.HazardRec) {
    Top.HazardRec = DAG->TII->CreateTargetMIHazardRecognizer(Itin, DAG);
  }
  if (!Bot.HazardRec) {
    Bot.HazardRec = DAG->TII->CreateTargetMIHazardRecognizer(Itin, DAG);
  }
  TopClusterID = InvalidClusterId;
  BotClusterID = InvalidClusterId;
}

void PostGenericScheduler::initPolicy(MachineBasicBlock::iterator Begin,
                                      MachineBasicBlock::iterator End,
                                      unsigned NumRegionInstrs) {
  const MachineFunction &MF = *Begin->getMF();

  // Default to top-down because it was implemented first and existing targets
  // expect that behavior by default.
  RegionPolicy.OnlyTopDown = true;
  RegionPolicy.OnlyBottomUp = false;

  // Allow the subtarget to override default policy.
  SchedRegion Region(Begin, End, NumRegionInstrs);
  MF.getSubtarget().overridePostRASchedPolicy(RegionPolicy, Region);

  // After subtarget overrides, apply command line options.
  if (PostRADirection == MISched::TopDown) {
    RegionPolicy.OnlyTopDown = true;
    RegionPolicy.OnlyBottomUp = false;
  } else if (PostRADirection == MISched::BottomUp) {
    RegionPolicy.OnlyTopDown = false;
    RegionPolicy.OnlyBottomUp = true;
  } else if (PostRADirection == MISched::Bidirectional) {
    RegionPolicy.OnlyBottomUp = false;
    RegionPolicy.OnlyTopDown = false;
  }

  BotIdx = NumRegionInstrs - 1;
  this->NumRegionInstrs = NumRegionInstrs;
}

void PostGenericScheduler::registerRoots() {
  Rem.CriticalPath = DAG->ExitSU.getDepth();

  // Some roots may not feed into ExitSU. Check all of them in case.
  for (const SUnit *SU : Bot.Available) {
    if (SU->getDepth() > Rem.CriticalPath)
      Rem.CriticalPath = SU->getDepth();
  }
  LLVM_DEBUG(dbgs() << "Critical Path: (PGS-RR) " << Rem.CriticalPath << '\n');
  if (DumpCriticalPathLength) {
    errs() << "Critical Path(PGS-RR ): " << Rem.CriticalPath << " \n";
  }
}

/// Apply a set of heuristics to a new candidate for PostRA scheduling.
///
/// \param Cand provides the policy and current best candidate.
/// \param TryCand refers to the next SUnit candidate, otherwise uninitialized.
/// \return \c true if TryCand is better than Cand (Reason is NOT NoCand)
bool PostGenericScheduler::tryCandidate(SchedCandidate &Cand,
                                        SchedCandidate &TryCand) {
  // Initialize the candidate if needed.
  if (!Cand.isValid()) {
    TryCand.Reason = FirstValid;
    return true;
  }

  // Prioritize instructions that read unbuffered resources by stall cycles.
  if (tryLess(Top.getLatencyStallCycles(TryCand.SU),
              Top.getLatencyStallCycles(Cand.SU), TryCand, Cand, Stall))
    return TryCand.Reason != NoCand;

  // Keep clustered nodes together.
  unsigned CandZoneCluster = Cand.AtTop ? TopClusterID : BotClusterID;
  unsigned TryCandZoneCluster = TryCand.AtTop ? TopClusterID : BotClusterID;
  bool CandIsClusterSucc =
      isTheSameCluster(CandZoneCluster, Cand.SU->ParentClusterIdx);
  bool TryCandIsClusterSucc =
      isTheSameCluster(TryCandZoneCluster, TryCand.SU->ParentClusterIdx);

  if (tryGreater(TryCandIsClusterSucc, CandIsClusterSucc, TryCand, Cand,
                 Cluster))
    return TryCand.Reason != NoCand;
  // Avoid critical resource consumption and balance the schedule.
  if (tryLess(TryCand.ResDelta.CritResources, Cand.ResDelta.CritResources,
              TryCand, Cand, ResourceReduce))
    return TryCand.Reason != NoCand;
  if (tryGreater(TryCand.ResDelta.DemandedResources,
                 Cand.ResDelta.DemandedResources,
                 TryCand, Cand, ResourceDemand))
    return TryCand.Reason != NoCand;

  // We only compare a subset of features when comparing nodes between
  // Top and Bottom boundary.
  if (Cand.AtTop == TryCand.AtTop) {
    // Avoid serializing long latency dependence chains.
    if (Cand.Policy.ReduceLatency &&
        tryLatency(TryCand, Cand, Cand.AtTop ? Top : Bot))
      return TryCand.Reason != NoCand;
  }

  // Fall through to original instruction order.
  if (TryCand.SU->NodeNum < Cand.SU->NodeNum) {
    TryCand.Reason = NodeOrder;
    return true;
  }

  return false;
}

void PostGenericScheduler::pickNodeFromQueue(SchedBoundary &Zone,
                                             SchedCandidate &Cand) {
  ReadyQueue &Q = Zone.Available;
  for (SUnit *SU : Q) {
    SchedCandidate TryCand(Cand.Policy);
    TryCand.SU = SU;
    TryCand.AtTop = Zone.isTop();
    TryCand.initResourceDelta(DAG, SchedModel);
    if (tryCandidate(Cand, TryCand)) {
      Cand.setBest(TryCand);
      LLVM_DEBUG(traceCandidate(Cand));
    }
  }
}

/// Pick the best candidate node from either the top or bottom queue.
SUnit *PostGenericScheduler::pickNodeBidirectional(bool &IsTopNode) {
  // FIXME: This is similiar to GenericScheduler::pickNodeBidirectional. Factor
  // out common parts.

  // Schedule as far as possible in the direction of no choice. This is most
  // efficient, but also provides the best heuristics for CriticalPSets.
  if (SUnit *SU = Bot.pickOnlyChoice()) {
    IsTopNode = false;
    tracePick(Only1, /*IsTopNode=*/false, /*IsPostRA=*/true);
    return SU;
  }
  if (SUnit *SU = Top.pickOnlyChoice()) {
    IsTopNode = true;
    tracePick(Only1, /*IsTopNode=*/true, /*IsPostRA=*/true);
    return SU;
  }
  // Set the bottom-up policy based on the state of the current bottom zone and
  // the instructions outside the zone, including the top zone.
  CandPolicy BotPolicy;
  setPolicy(BotPolicy, /*IsPostRA=*/true, Bot, &Top);
  // Set the top-down policy based on the state of the current top zone and
  // the instructions outside the zone, including the bottom zone.
  CandPolicy TopPolicy;
  setPolicy(TopPolicy, /*IsPostRA=*/true, Top, &Bot);

  // See if BotCand is still valid (because we previously scheduled from Top).
  LLVM_DEBUG(dbgs() << "Picking from Bot:\n");
  if (!BotCand.isValid() || BotCand.SU->isScheduled ||
      BotCand.Policy != BotPolicy) {
    BotCand.reset(CandPolicy());
    pickNodeFromQueue(Bot, BotCand);
    assert(BotCand.Reason != NoCand && "failed to find the first candidate");
  } else {
    LLVM_DEBUG(traceCandidate(BotCand));
#ifndef NDEBUG
    if (VerifyScheduling) {
      SchedCandidate TCand;
      TCand.reset(CandPolicy());
      pickNodeFromQueue(Bot, BotCand);
      assert(TCand.SU == BotCand.SU &&
             "Last pick result should correspond to re-picking right now");
    }
#endif
  }

  // Check if the top Q has a better candidate.
  LLVM_DEBUG(dbgs() << "Picking from Top:\n");
  if (!TopCand.isValid() || TopCand.SU->isScheduled ||
      TopCand.Policy != TopPolicy) {
    TopCand.reset(CandPolicy());
    pickNodeFromQueue(Top, TopCand);
    assert(TopCand.Reason != NoCand && "failed to find the first candidate");
  } else {
    LLVM_DEBUG(traceCandidate(TopCand));
#ifndef NDEBUG
    if (VerifyScheduling) {
      SchedCandidate TCand;
      TCand.reset(CandPolicy());
      pickNodeFromQueue(Top, TopCand);
      assert(TCand.SU == TopCand.SU &&
             "Last pick result should correspond to re-picking right now");
    }
#endif
  }

  // Pick best from BotCand and TopCand.
  assert(BotCand.isValid());
  assert(TopCand.isValid());
  SchedCandidate Cand = BotCand;
  TopCand.Reason = NoCand;
  if (tryCandidate(Cand, TopCand)) {
    Cand.setBest(TopCand);
    LLVM_DEBUG(traceCandidate(Cand));
  }

  IsTopNode = Cand.AtTop;
  tracePick(Cand, /*IsPostRA=*/true);
  return Cand.SU;
}

/// Pick the next node to schedule.
SUnit *PostGenericScheduler::pickNode(bool &IsTopNode) {
  if (DAG->top() == DAG->bottom()) {
    assert(Top.Available.empty() && Top.Pending.empty() &&
           Bot.Available.empty() && Bot.Pending.empty() && "ReadyQ garbage");
    return nullptr;
  }
  SUnit *SU;
  do {
    if (RegionPolicy.OnlyBottomUp) {
      SU = Bot.pickOnlyChoice();
      if (SU) {
        tracePick(Only1, /*IsTopNode=*/true, /*IsPostRA=*/true);
      } else {
        CandPolicy NoPolicy;
        BotCand.reset(NoPolicy);
        // Set the bottom-up policy based on the state of the current bottom
        // zone and the instructions outside the zone, including the top zone.
        setPolicy(BotCand.Policy, /*IsPostRA=*/true, Bot, nullptr);
        pickNodeFromQueue(Bot, BotCand);
        assert(BotCand.Reason != NoCand && "failed to find a candidate");
        tracePick(BotCand, /*IsPostRA=*/true);
        SU = BotCand.SU;
      }
      IsTopNode = false;
    } else if (RegionPolicy.OnlyTopDown) {
      SU = Top.pickOnlyChoice();
      if (SU) {
        tracePick(Only1, /*IsTopNode=*/true, /*IsPostRA=*/true);
      } else {
        CandPolicy NoPolicy;
        TopCand.reset(NoPolicy);
        // Set the top-down policy based on the state of the current top zone
        // and the instructions outside the zone, including the bottom zone.
        setPolicy(TopCand.Policy, /*IsPostRA=*/true, Top, nullptr);
        pickNodeFromQueue(Top, TopCand);
        assert(TopCand.Reason != NoCand && "failed to find a candidate");
        tracePick(TopCand, /*IsPostRA=*/true);
        SU = TopCand.SU;
      }
      IsTopNode = true;
    } else {
      SU = pickNodeBidirectional(IsTopNode);
    }
  } while (SU->isScheduled);

  if (SU->isTopReady())
    Top.removeReady(SU);
  if (SU->isBottomReady())
    Bot.removeReady(SU);

  LLVM_DEBUG(dbgs() << "Scheduling SU(" << SU->NodeNum << ") "
                    << *SU->getInstr());

  if (IsTopNode) {
    if (SU->NodeNum == TopIdx++)
      ++NumInstrsInSourceOrderPostRA;
  } else {
    assert(BotIdx < NumRegionInstrs && "out of bounds");
    if (SU->NodeNum == BotIdx--)
      ++NumInstrsInSourceOrderPostRA;
  }

  NumInstrsScheduledPostRA += 1;

  return SU;
}

/// Called after ScheduleDAGMI has scheduled an instruction and updated
/// scheduled/remaining flags in the DAG nodes.
void PostGenericScheduler::schedNode(SUnit *SU, bool IsTopNode) {
  if (IsTopNode) {
    SU->TopReadyCycle = std::max(SU->TopReadyCycle, Top.getCurrCycle());
    TopClusterID = SU->ParentClusterIdx;
    Top.bumpNode(SU);
  } else {
    SU->BotReadyCycle = std::max(SU->BotReadyCycle, Bot.getCurrCycle());
    BotClusterID = SU->ParentClusterIdx;
    Bot.bumpNode(SU);
  }
}

//===----------------------------------------------------------------------===//
// ILP Scheduler. Currently for experimental analysis of heuristics.
//===----------------------------------------------------------------------===//

namespace {

/// Order nodes by the ILP metric.
struct ILPOrder {
  const SchedDFSResult *DFSResult = nullptr;
  const BitVector *ScheduledTrees = nullptr;
  bool MaximizeILP;

  ILPOrder(bool MaxILP) : MaximizeILP(MaxILP) {}

  /// Apply a less-than relation on node priority.
  ///
  /// (Return true if A comes after B in the Q.)
  bool operator()(const SUnit *A, const SUnit *B) const {
    unsigned SchedTreeA = DFSResult->getSubtreeID(A);
    unsigned SchedTreeB = DFSResult->getSubtreeID(B);
    if (SchedTreeA != SchedTreeB) {
      // Unscheduled trees have lower priority.
      if (ScheduledTrees->test(SchedTreeA) != ScheduledTrees->test(SchedTreeB))
        return ScheduledTrees->test(SchedTreeB);

      // Trees with shallower connections have lower priority.
      if (DFSResult->getSubtreeLevel(SchedTreeA)
          != DFSResult->getSubtreeLevel(SchedTreeB)) {
        return DFSResult->getSubtreeLevel(SchedTreeA)
          < DFSResult->getSubtreeLevel(SchedTreeB);
      }
    }
    if (MaximizeILP)
      return DFSResult->getILP(A) < DFSResult->getILP(B);
    else
      return DFSResult->getILP(A) > DFSResult->getILP(B);
  }
};

/// Schedule based on the ILP metric.
class ILPScheduler : public MachineSchedStrategy {
  ScheduleDAGMILive *DAG = nullptr;
  ILPOrder Cmp;

  std::vector<SUnit*> ReadyQ;

public:
  ILPScheduler(bool MaximizeILP) : Cmp(MaximizeILP) {}

  void initialize(ScheduleDAGMI *dag) override {
    assert(dag->hasVRegLiveness() && "ILPScheduler needs vreg liveness");
    DAG = static_cast<ScheduleDAGMILive*>(dag);
    DAG->computeDFSResult();
    Cmp.DFSResult = DAG->getDFSResult();
    Cmp.ScheduledTrees = &DAG->getScheduledTrees();
    ReadyQ.clear();
  }

  void registerRoots() override {
    // Restore the heap in ReadyQ with the updated DFS results.
    std::make_heap(ReadyQ.begin(), ReadyQ.end(), Cmp);
  }

  /// Implement MachineSchedStrategy interface.
  /// -----------------------------------------

  /// Callback to select the highest priority node from the ready Q.
  SUnit *pickNode(bool &IsTopNode) override {
    if (ReadyQ.empty()) return nullptr;
    std::pop_heap(ReadyQ.begin(), ReadyQ.end(), Cmp);
    SUnit *SU = ReadyQ.back();
    ReadyQ.pop_back();
    IsTopNode = false;
    LLVM_DEBUG(dbgs() << "Pick node "
                      << "SU(" << SU->NodeNum << ") "
                      << " ILP: " << DAG->getDFSResult()->getILP(SU)
                      << " Tree: " << DAG->getDFSResult()->getSubtreeID(SU)
                      << " @"
                      << DAG->getDFSResult()->getSubtreeLevel(
                             DAG->getDFSResult()->getSubtreeID(SU))
                      << '\n'
                      << "Scheduling " << *SU->getInstr());
    return SU;
  }

  /// Scheduler callback to notify that a new subtree is scheduled.
  void scheduleTree(unsigned SubtreeID) override {
    std::make_heap(ReadyQ.begin(), ReadyQ.end(), Cmp);
  }

  /// Callback after a node is scheduled. Mark a newly scheduled tree, notify
  /// DFSResults, and resort the priority Q.
  void schedNode(SUnit *SU, bool IsTopNode) override {
    assert(!IsTopNode && "SchedDFSResult needs bottom-up");
  }

  void releaseTopNode(SUnit *) override { /*only called for top roots*/ }

  void releaseBottomNode(SUnit *SU) override {
    ReadyQ.push_back(SU);
    std::push_heap(ReadyQ.begin(), ReadyQ.end(), Cmp);
  }
};

} // end anonymous namespace

static ScheduleDAGInstrs *createILPMaxScheduler(MachineSchedContext *C) {
  return new ScheduleDAGMILive(C, std::make_unique<ILPScheduler>(true));
}
static ScheduleDAGInstrs *createILPMinScheduler(MachineSchedContext *C) {
  return new ScheduleDAGMILive(C, std::make_unique<ILPScheduler>(false));
}

static MachineSchedRegistry ILPMaxRegistry(
  "ilpmax", "Schedule bottom-up for max ILP", createILPMaxScheduler);
static MachineSchedRegistry ILPMinRegistry(
  "ilpmin", "Schedule bottom-up for min ILP", createILPMinScheduler);

//===----------------------------------------------------------------------===//
// Machine Instruction Shuffler for Correctness Testing
//===----------------------------------------------------------------------===//

#ifndef NDEBUG
namespace {

/// Apply a less-than relation on the node order, which corresponds to the
/// instruction order prior to scheduling. IsReverse implements greater-than.
template<bool IsReverse>
struct SUnitOrder {
  bool operator()(SUnit *A, SUnit *B) const {
    if (IsReverse)
      return A->NodeNum > B->NodeNum;
    else
      return A->NodeNum < B->NodeNum;
  }
};

/// Reorder instructions as much as possible.
class InstructionShuffler : public MachineSchedStrategy {
  bool IsAlternating;
  bool IsTopDown;

  // Using a less-than relation (SUnitOrder<false>) for the TopQ priority
  // gives nodes with a higher number higher priority causing the latest
  // instructions to be scheduled first.
  PriorityQueue<SUnit*, std::vector<SUnit*>, SUnitOrder<false>>
    TopQ;

  // When scheduling bottom-up, use greater-than as the queue priority.
  PriorityQueue<SUnit*, std::vector<SUnit*>, SUnitOrder<true>>
    BottomQ;

public:
  InstructionShuffler(bool alternate, bool topdown)
    : IsAlternating(alternate), IsTopDown(topdown) {}

  void initialize(ScheduleDAGMI*) override {
    TopQ.clear();
    BottomQ.clear();
  }

  /// Implement MachineSchedStrategy interface.
  /// -----------------------------------------

  SUnit *pickNode(bool &IsTopNode) override {
    SUnit *SU;
    if (IsTopDown) {
      do {
        if (TopQ.empty()) return nullptr;
        SU = TopQ.top();
        TopQ.pop();
      } while (SU->isScheduled);
      IsTopNode = true;
    } else {
      do {
        if (BottomQ.empty()) return nullptr;
        SU = BottomQ.top();
        BottomQ.pop();
      } while (SU->isScheduled);
      IsTopNode = false;
    }
    if (IsAlternating)
      IsTopDown = !IsTopDown;
    return SU;
  }

  void schedNode(SUnit *SU, bool IsTopNode) override {}

  void releaseTopNode(SUnit *SU) override {
    TopQ.push(SU);
  }
  void releaseBottomNode(SUnit *SU) override {
    BottomQ.push(SU);
  }
};

} // end anonymous namespace

static ScheduleDAGInstrs *createInstructionShuffler(MachineSchedContext *C) {
  bool Alternate =
      PreRADirection != MISched::TopDown && PreRADirection != MISched::BottomUp;
  bool TopDown = PreRADirection != MISched::BottomUp;
  return new ScheduleDAGMILive(
      C, std::make_unique<InstructionShuffler>(Alternate, TopDown));
}

static MachineSchedRegistry ShufflerRegistry(
  "shuffle", "Shuffle machine instructions alternating directions",
  createInstructionShuffler);
#endif // !NDEBUG

//===----------------------------------------------------------------------===//
// GraphWriter support for ScheduleDAGMILive.
//===----------------------------------------------------------------------===//

#ifndef NDEBUG
namespace llvm {

template<> struct GraphTraits<
  ScheduleDAGMI*> : public GraphTraits<ScheduleDAG*> {};

template<>
struct DOTGraphTraits<ScheduleDAGMI*> : public DefaultDOTGraphTraits {
  DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}

  static std::string getGraphName(const ScheduleDAG *G) {
    return std::string(G->MF.getName());
  }

  static bool renderGraphFromBottomUp() {
    return true;
  }

  static bool isNodeHidden(const SUnit *Node, const ScheduleDAG *G) {
    if (ViewMISchedCutoff == 0)
      return false;
    return (Node->Preds.size() > ViewMISchedCutoff
         || Node->Succs.size() > ViewMISchedCutoff);
  }

  /// If you want to override the dot attributes printed for a particular
  /// edge, override this method.
  static std::string getEdgeAttributes(const SUnit *Node,
                                       SUnitIterator EI,
                                       const ScheduleDAG *Graph) {
    if (EI.isArtificialDep())
      return "color=cyan,style=dashed";
    if (EI.isCtrlDep())
      return "color=blue,style=dashed";
    return "";
  }

  static std::string getNodeLabel(const SUnit *SU, const ScheduleDAG *G) {
    std::string Str;
    raw_string_ostream SS(Str);
    const ScheduleDAGMI *DAG = static_cast<const ScheduleDAGMI*>(G);
    const SchedDFSResult *DFS = DAG->hasVRegLiveness() ?
      static_cast<const ScheduleDAGMILive*>(G)->getDFSResult() : nullptr;
    SS << "SU:" << SU->NodeNum;
    if (DFS)
      SS << " I:" << DFS->getNumInstrs(SU);
    return Str;
  }

  static std::string getNodeDescription(const SUnit *SU, const ScheduleDAG *G) {
    return G->getGraphNodeLabel(SU);
  }

  static std::string getNodeAttributes(const SUnit *N, const ScheduleDAG *G) {
    std::string Str("shape=Mrecord");
    const ScheduleDAGMI *DAG = static_cast<const ScheduleDAGMI*>(G);
    const SchedDFSResult *DFS = DAG->hasVRegLiveness() ?
      static_cast<const ScheduleDAGMILive*>(G)->getDFSResult() : nullptr;
    if (DFS) {
      Str += ",style=filled,fillcolor=\"#";
      Str += DOT::getColorString(DFS->getSubtreeID(N));
      Str += '"';
    }
    return Str;
  }
};

} // end namespace llvm
#endif // NDEBUG

/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
/// rendered using 'dot'.
void ScheduleDAGMI::viewGraph(const Twine &Name, const Twine &Title) {
#ifndef NDEBUG
  ViewGraph(this, Name, false, Title);
#else
  errs() << "ScheduleDAGMI::viewGraph is only available in debug builds on "
         << "systems with Graphviz or gv!\n";
#endif  // NDEBUG
}

/// Out-of-line implementation with no arguments is handy for gdb.
void ScheduleDAGMI::viewGraph() {
  viewGraph(getDAGName(), "Scheduling-Units Graph for " + getDAGName());
}

/// Sort predicate for the intervals stored in an instance of
/// ResourceSegments. Intervals are always disjoint (no intersection
/// for any pairs of intervals), therefore we can sort the totality of
/// the intervals by looking only at the left boundary.
static bool sortIntervals(const ResourceSegments::IntervalTy &A,
                          const ResourceSegments::IntervalTy &B) {
  return A.first < B.first;
}

unsigned ResourceSegments::getFirstAvailableAt(
    unsigned CurrCycle, unsigned AcquireAtCycle, unsigned ReleaseAtCycle,
    std::function<ResourceSegments::IntervalTy(unsigned, unsigned, unsigned)>
        IntervalBuilder) const {
  assert(llvm::is_sorted(_Intervals, sortIntervals) &&
         "Cannot execute on an un-sorted set of intervals.");

  // Zero resource usage is allowed by TargetSchedule.td but we do not construct
  // a ResourceSegment interval for that situation.
  if (AcquireAtCycle == ReleaseAtCycle)
    return CurrCycle;

  unsigned RetCycle = CurrCycle;
  ResourceSegments::IntervalTy NewInterval =
      IntervalBuilder(RetCycle, AcquireAtCycle, ReleaseAtCycle);
  for (auto &Interval : _Intervals) {
    if (!intersects(NewInterval, Interval))
      continue;

    // Move the interval right next to the top of the one it
    // intersects.
    assert(Interval.second > NewInterval.first &&
           "Invalid intervals configuration.");
    RetCycle += (unsigned)Interval.second - (unsigned)NewInterval.first;
    NewInterval = IntervalBuilder(RetCycle, AcquireAtCycle, ReleaseAtCycle);
  }
  return RetCycle;
}

void ResourceSegments::add(ResourceSegments::IntervalTy A,
                           const unsigned CutOff) {
  assert(A.first <= A.second && "Cannot add negative resource usage");
  assert(CutOff > 0 && "0-size interval history has no use.");
  // Zero resource usage is allowed by TargetSchedule.td, in the case that the
  // instruction needed the resource to be available but does not use it.
  // However, ResourceSegment represents an interval that is closed on the left
  // and open on the right. It is impossible to represent an empty interval when
  // the left is closed. Do not add it to Intervals.
  if (A.first == A.second)
    return;

  assert(all_of(_Intervals,
                [&A](const ResourceSegments::IntervalTy &Interval) -> bool {
                  return !intersects(A, Interval);
                }) &&
         "A resource is being overwritten");
  _Intervals.push_back(A);

  sortAndMerge();

  // Do not keep the full history of the intervals, just the
  // latest #CutOff.
  while (_Intervals.size() > CutOff)
    _Intervals.pop_front();
}

bool ResourceSegments::intersects(ResourceSegments::IntervalTy A,
                                  ResourceSegments::IntervalTy B) {
  assert(A.first <= A.second && "Invalid interval");
  assert(B.first <= B.second && "Invalid interval");

  // Share one boundary.
  if ((A.first == B.first) || (A.second == B.second))
    return true;

  // full intersersect: [    ***     )  B
  //                        [***)       A
  if ((A.first > B.first) && (A.second < B.second))
    return true;

  // right intersect: [     ***)        B
  //                       [***      )  A
  if ((A.first > B.first) && (A.first < B.second) && (A.second > B.second))
    return true;

  // left intersect:      [***      )  B
  //                 [     ***)        A
  if ((A.first < B.first) && (B.first < A.second) && (B.second > B.first))
    return true;

  return false;
}

void ResourceSegments::sortAndMerge() {
  if (_Intervals.size() <= 1)
    return;

  // First sort the collection.
  _Intervals.sort(sortIntervals);

  // can use next because I have at least 2 elements in the list
  auto next = std::next(std::begin(_Intervals));
  auto E = std::end(_Intervals);
  for (; next != E; ++next) {
    if (std::prev(next)->second >= next->first) {
      next->first = std::prev(next)->first;
      _Intervals.erase(std::prev(next));
      continue;
    }
  }
}
