//===- 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");

cl::opt<MISched::Direction> llvm::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> llvm::VerifyScheduling(
    "verify-misched", cl::Hidden,
    cl::desc("Verify machine instrs before and after machine scheduling"));

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

#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

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

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

// 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

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

/// 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

/// 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 llvm::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 llvm::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 llvm::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;
}

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();
  }
}

bool llvm::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 llvm::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 llvm::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;
}

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;
  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);
  }
  assert(!SU->isScheduled && "SUnit scheduled twice.");

  // 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;
  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);
  }
  assert(!SU->isScheduled && "SUnit scheduled twice.");

  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

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

template <>
struct llvm::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;
  }
};

#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;
    }
  }
}
