//===----- SchedulePostRAList.cpp - list 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
//
//===----------------------------------------------------------------------===//
//
// This implements a top-down list scheduler, using standard algorithms.
// The basic approach uses a priority queue of available nodes to schedule.
// One at a time, nodes are taken from the priority queue (thus in priority
// order), checked for legality to schedule, and emitted if legal.
//
// Nodes may not be legal to schedule either due to structural hazards (e.g.
// pipeline or resource constraints) or because an input to the instruction has
// not completed execution.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/PostRASchedulerList.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/AntiDepBreaker.h"
#include "llvm/CodeGen/LatencyPriorityQueue.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
#include "llvm/CodeGen/ScheduleDAGMutation.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;

#define DEBUG_TYPE "post-RA-sched"

STATISTIC(NumNoops, "Number of noops inserted");
STATISTIC(NumStalls, "Number of pipeline stalls");
STATISTIC(NumFixedAnti, "Number of fixed anti-dependencies");

// Post-RA scheduling is enabled with
// TargetSubtargetInfo.enablePostRAScheduler(). This flag can be used to
// override the target.
static cl::opt<bool>
EnablePostRAScheduler("post-RA-scheduler",
                       cl::desc("Enable scheduling after register allocation"),
                       cl::init(false), cl::Hidden);
static cl::opt<std::string>
EnableAntiDepBreaking("break-anti-dependencies",
                      cl::desc("Break post-RA scheduling anti-dependencies: "
                               "\"critical\", \"all\", or \"none\""),
                      cl::init("none"), cl::Hidden);

// If DebugDiv > 0 then only schedule MBB with (ID % DebugDiv) == DebugMod
static cl::opt<int>
DebugDiv("postra-sched-debugdiv",
                      cl::desc("Debug control MBBs that are scheduled"),
                      cl::init(0), cl::Hidden);
static cl::opt<int>
DebugMod("postra-sched-debugmod",
                      cl::desc("Debug control MBBs that are scheduled"),
                      cl::init(0), cl::Hidden);

AntiDepBreaker::~AntiDepBreaker() = default;

namespace {
class PostRAScheduler {
  const TargetInstrInfo *TII = nullptr;
  MachineLoopInfo *MLI = nullptr;
  AliasAnalysis *AA = nullptr;
  const TargetMachine *TM = nullptr;
  const RegisterClassInfo *RegClassInfo = nullptr;

public:
  PostRAScheduler(MachineFunction &MF, MachineLoopInfo *MLI, AliasAnalysis *AA,
                  const TargetMachine *TM,
                  const RegisterClassInfo *RegClassInfo)
      : TII(MF.getSubtarget().getInstrInfo()), MLI(MLI), AA(AA), TM(TM),
        RegClassInfo(RegClassInfo) {}
  bool run(MachineFunction &MF);
};

class PostRASchedulerLegacy : public MachineFunctionPass {
public:
  static char ID;
  PostRASchedulerLegacy() : MachineFunctionPass(ID) {}

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

  MachineFunctionProperties getRequiredProperties() const override {
    return MachineFunctionProperties().setNoVRegs();
  }

  bool runOnMachineFunction(MachineFunction &Fn) override;
};
char PostRASchedulerLegacy::ID = 0;

class SchedulePostRATDList : public ScheduleDAGInstrs {
  /// AvailableQueue - The priority queue to use for the available SUnits.
  ///
  LatencyPriorityQueue AvailableQueue;

  /// PendingQueue - This contains all of the instructions whose operands have
  /// been issued, but their results are not ready yet (due to the latency of
  /// the operation).  Once the operands becomes available, the instruction is
  /// added to the AvailableQueue.
  std::vector<SUnit *> PendingQueue;

  /// HazardRec - The hazard recognizer to use.
  ScheduleHazardRecognizer *HazardRec;

  /// AntiDepBreak - Anti-dependence breaking object, or NULL if none
  AntiDepBreaker *AntiDepBreak;

  /// AA - AliasAnalysis for making memory reference queries.
  AliasAnalysis *AA;

  /// The schedule. Null SUnit*'s represent noop instructions.
  std::vector<SUnit *> Sequence;

  /// Ordered list of DAG postprocessing steps.
  std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;

  /// The index in BB of RegionEnd.
  ///
  /// This is the instruction number from the top of the current block, not
  /// the SlotIndex. It is only used by the AntiDepBreaker.
  unsigned EndIndex = 0;

public:
  SchedulePostRATDList(
      MachineFunction &MF, MachineLoopInfo &MLI, AliasAnalysis *AA,
      const RegisterClassInfo &,
      TargetSubtargetInfo::AntiDepBreakMode AntiDepMode,
      SmallVectorImpl<const TargetRegisterClass *> &CriticalPathRCs);

  ~SchedulePostRATDList() override;

  /// startBlock - Initialize register live-range state for scheduling in
  /// this block.
  ///
  void startBlock(MachineBasicBlock *BB) override;

  // Set the index of RegionEnd within the current BB.
  void setEndIndex(unsigned EndIdx) { EndIndex = EndIdx; }

  /// Initialize the scheduler state for the next scheduling region.
  void enterRegion(MachineBasicBlock *bb, MachineBasicBlock::iterator begin,
                   MachineBasicBlock::iterator end,
                   unsigned regioninstrs) override;

  /// Notify that the scheduler has finished scheduling the current region.
  void exitRegion() override;

  /// Schedule - Schedule the instruction range using list scheduling.
  ///
  void schedule() override;

  void EmitSchedule();

  /// Observe - Update liveness information to account for the current
  /// instruction, which will not be scheduled.
  ///
  void Observe(MachineInstr &MI, unsigned Count);

  /// finishBlock - Clean up register live-range state.
  ///
  void finishBlock() override;

private:
  /// Apply each ScheduleDAGMutation step in order.
  void postProcessDAG();

  void ReleaseSucc(SUnit *SU, SDep *SuccEdge);
  void ReleaseSuccessors(SUnit *SU);
  void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle);
  void ListScheduleTopDown();

  void dumpSchedule() const;
  void emitNoop(unsigned CurCycle);
};
} // namespace

char &llvm::PostRASchedulerID = PostRASchedulerLegacy::ID;

INITIALIZE_PASS_BEGIN(PostRASchedulerLegacy, DEBUG_TYPE,
                      "Post RA top-down list latency scheduler", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineRegisterClassInfoWrapperPass)
INITIALIZE_PASS_END(PostRASchedulerLegacy, DEBUG_TYPE,
                    "Post RA top-down list latency scheduler", false, false)

SchedulePostRATDList::SchedulePostRATDList(
    MachineFunction &MF, MachineLoopInfo &MLI, AliasAnalysis *AA,
    const RegisterClassInfo &RCI,
    TargetSubtargetInfo::AntiDepBreakMode AntiDepMode,
    SmallVectorImpl<const TargetRegisterClass *> &CriticalPathRCs)
    : ScheduleDAGInstrs(MF, &MLI), AA(AA) {

  const InstrItineraryData *InstrItins =
      MF.getSubtarget().getInstrItineraryData();
  HazardRec =
      MF.getSubtarget().getInstrInfo()->CreateTargetPostRAHazardRecognizer(
          InstrItins, this);
  MF.getSubtarget().getPostRAMutations(Mutations);

  assert((AntiDepMode == TargetSubtargetInfo::ANTIDEP_NONE ||
          MRI.tracksLiveness()) &&
         "Live-ins must be accurate for anti-dependency breaking");
  AntiDepBreak = ((AntiDepMode == TargetSubtargetInfo::ANTIDEP_ALL)
                      ? createAggressiveAntiDepBreaker(MF, RCI, CriticalPathRCs)
                      : ((AntiDepMode == TargetSubtargetInfo::ANTIDEP_CRITICAL)
                             ? createCriticalAntiDepBreaker(MF, RCI)
                             : nullptr));
}

SchedulePostRATDList::~SchedulePostRATDList() {
  delete HazardRec;
  delete AntiDepBreak;
}

/// Initialize state associated with the next scheduling region.
void SchedulePostRATDList::enterRegion(MachineBasicBlock *bb,
                 MachineBasicBlock::iterator begin,
                 MachineBasicBlock::iterator end,
                 unsigned regioninstrs) {
  ScheduleDAGInstrs::enterRegion(bb, begin, end, regioninstrs);
  Sequence.clear();
}

/// Print the schedule before exiting the region.
void SchedulePostRATDList::exitRegion() {
  LLVM_DEBUG({
    dbgs() << "*** Final schedule ***\n";
    dumpSchedule();
    dbgs() << '\n';
  });
  ScheduleDAGInstrs::exitRegion();
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
/// dumpSchedule - dump the scheduled Sequence.
LLVM_DUMP_METHOD void SchedulePostRATDList::dumpSchedule() const {
  for (const SUnit *SU : Sequence) {
    if (SU)
      dumpNode(*SU);
    else
      dbgs() << "**** NOOP ****\n";
  }
}
#endif

static bool enablePostRAScheduler(const TargetSubtargetInfo &ST,
                                  CodeGenOptLevel OptLevel) {
  // Check for explicit enable/disable of post-ra scheduling.
  if (EnablePostRAScheduler.getPosition() > 0)
    return EnablePostRAScheduler;

  return ST.enablePostRAScheduler() &&
         OptLevel >= ST.getOptLevelToEnablePostRAScheduler();
}

bool PostRAScheduler::run(MachineFunction &MF) {
  const auto &Subtarget = MF.getSubtarget();
  // Check that post-RA scheduling is enabled for this target.
  if (!enablePostRAScheduler(Subtarget, TM->getOptLevel()))
    return false;

  TargetSubtargetInfo::AntiDepBreakMode AntiDepMode =
      Subtarget.getAntiDepBreakMode();
  if (EnableAntiDepBreaking.getPosition() > 0) {
    AntiDepMode = (EnableAntiDepBreaking == "all")
      ? TargetSubtargetInfo::ANTIDEP_ALL
      : ((EnableAntiDepBreaking == "critical")
         ? TargetSubtargetInfo::ANTIDEP_CRITICAL
         : TargetSubtargetInfo::ANTIDEP_NONE);
  }
  SmallVector<const TargetRegisterClass *, 4> CriticalPathRCs;
  Subtarget.getCriticalPathRCs(CriticalPathRCs);

  LLVM_DEBUG(dbgs() << "PostRAScheduler\n");

  SchedulePostRATDList Scheduler(MF, *MLI, AA, *RegClassInfo, AntiDepMode,
                                 CriticalPathRCs);

  // Loop over all of the basic blocks
  for (auto &MBB : MF) {
#ifndef NDEBUG
    // If DebugDiv > 0 then only schedule MBB with (ID % DebugDiv) == DebugMod
    if (DebugDiv > 0) {
      static int bbcnt = 0;
      if (bbcnt++ % DebugDiv != DebugMod)
        continue;
      dbgs() << "*** DEBUG scheduling " << MF.getName() << ":"
             << printMBBReference(MBB) << " ***\n";
    }
#endif

    // Initialize register live-range state for scheduling in this block.
    Scheduler.startBlock(&MBB);

    // Schedule each sequence of instructions not interrupted by a label
    // or anything else that effectively needs to shut down scheduling.
    MachineBasicBlock::iterator Current = MBB.end();
    unsigned Count = MBB.size(), CurrentCount = Count;
    for (MachineBasicBlock::iterator I = Current; I != MBB.begin();) {
      MachineInstr &MI = *std::prev(I);
      --Count;
      // Calls are not scheduling boundaries before register allocation, but
      // post-ra we don't gain anything by scheduling across calls since we
      // don't need to worry about register pressure.
      if (MI.isCall() || TII->isSchedulingBoundary(MI, &MBB, MF)) {
        Scheduler.enterRegion(&MBB, I, Current, CurrentCount - Count);
        Scheduler.setEndIndex(CurrentCount);
        Scheduler.schedule();
        Scheduler.exitRegion();
        Scheduler.EmitSchedule();
        Current = &MI;
        CurrentCount = Count;
        Scheduler.Observe(MI, CurrentCount);
      }
      I = MI;
      if (MI.isBundle())
        Count -= MI.getBundleSize();
    }
    assert(Count == 0 && "Instruction count mismatch!");
    assert((MBB.begin() == Current || CurrentCount != 0) &&
           "Instruction count mismatch!");
    Scheduler.enterRegion(&MBB, MBB.begin(), Current, CurrentCount);
    Scheduler.setEndIndex(CurrentCount);
    Scheduler.schedule();
    Scheduler.exitRegion();
    Scheduler.EmitSchedule();

    // Clean up register live-range state.
    Scheduler.finishBlock();

    // Update register kills
    Scheduler.fixupKills(MBB);
  }

  return true;
}

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

  MachineLoopInfo *MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
  AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
  const TargetMachine *TM =
      &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
  RegisterClassInfo *RegClassInfo =
      &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
  PostRAScheduler Impl(MF, MLI, AA, TM, RegClassInfo);
  return Impl.run(MF);
}

PreservedAnalyses
PostRASchedulerPass::run(MachineFunction &MF,
                         MachineFunctionAnalysisManager &MFAM) {
  MFPropsModifier _(*this, MF);

  MachineLoopInfo *MLI = &MFAM.getResult<MachineLoopAnalysis>(MF);
  auto &FAM = MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
                  .getManager();
  AliasAnalysis *AA = &FAM.getResult<AAManager>(MF.getFunction());
  const RegisterClassInfo &RegClassInfo =
      MFAM.getResult<MachineRegisterClassAnalysis>(MF);
  PostRAScheduler Impl(MF, MLI, AA, TM, &RegClassInfo);
  bool Changed = Impl.run(MF);
  if (!Changed)
    return PreservedAnalyses::all();

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

/// StartBlock - Initialize register live-range state for scheduling in
/// this block.
///
void SchedulePostRATDList::startBlock(MachineBasicBlock *BB) {
  // Call the superclass.
  ScheduleDAGInstrs::startBlock(BB);

  // Reset the hazard recognizer and anti-dep breaker.
  HazardRec->Reset();
  if (AntiDepBreak)
    AntiDepBreak->StartBlock(BB);
}

/// Schedule - Schedule the instruction range using list scheduling.
///
void SchedulePostRATDList::schedule() {
  // Build the scheduling graph.
  buildSchedGraph(AA);

  if (AntiDepBreak) {
    unsigned Broken =
      AntiDepBreak->BreakAntiDependencies(SUnits, RegionBegin, RegionEnd,
                                          EndIndex, DbgValues);

    if (Broken != 0) {
      // We made changes. Update the dependency graph.
      // Theoretically we could update the graph in place:
      // When a live range is changed to use a different register, remove
      // the def's anti-dependence *and* output-dependence edges due to
      // that register, and add new anti-dependence and output-dependence
      // edges based on the next live range of the register.
      ScheduleDAG::clearDAG();
      buildSchedGraph(AA);

      NumFixedAnti += Broken;
    }
  }

  postProcessDAG();

  LLVM_DEBUG(dbgs() << "********** List Scheduling **********\n");
  LLVM_DEBUG(dump());

  AvailableQueue.initNodes(SUnits);
  ListScheduleTopDown();
  AvailableQueue.releaseState();
}

/// Observe - Update liveness information to account for the current
/// instruction, which will not be scheduled.
///
void SchedulePostRATDList::Observe(MachineInstr &MI, unsigned Count) {
  if (AntiDepBreak)
    AntiDepBreak->Observe(MI, Count, EndIndex);
}

/// FinishBlock - Clean up register live-range state.
///
void SchedulePostRATDList::finishBlock() {
  if (AntiDepBreak)
    AntiDepBreak->FinishBlock();

  // Call the superclass.
  ScheduleDAGInstrs::finishBlock();
}

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

//===----------------------------------------------------------------------===//
//  Top-Down Scheduling
//===----------------------------------------------------------------------===//

/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to
/// the PendingQueue if the count reaches zero.
void SchedulePostRATDList::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
  --SuccSU->NumPredsLeft;

  // Standard scheduler algorithms will recompute the depth of the successor
  // here as such:
  //   SuccSU->setDepthToAtLeast(SU->getDepth() + SuccEdge->getLatency());
  //
  // However, we lazily compute node depth instead. Note that
  // ScheduleNodeTopDown has already updated the depth of this node which causes
  // all descendents to be marked dirty. Setting the successor depth explicitly
  // here would cause depth to be recomputed for all its ancestors. If the
  // successor is not yet ready (because of a transitively redundant edge) then
  // this causes depth computation to be quadratic in the size of the DAG.

  // If all the node's predecessors are scheduled, this node is ready
  // to be scheduled. Ignore the special ExitSU node.
  if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU)
    PendingQueue.push_back(SuccSU);
}

/// ReleaseSuccessors - Call ReleaseSucc on each of SU's successors.
void SchedulePostRATDList::ReleaseSuccessors(SUnit *SU) {
  for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
       I != E; ++I) {
    ReleaseSucc(SU, &*I);
  }
}

/// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending
/// count of its successors. If a successor pending count is zero, add it to
/// the Available queue.
void SchedulePostRATDList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) {
  LLVM_DEBUG(dbgs() << "*** Scheduling [" << CurCycle << "]: ");
  LLVM_DEBUG(dumpNode(*SU));

  Sequence.push_back(SU);
  assert(CurCycle >= SU->getDepth() &&
         "Node scheduled above its depth!");
  SU->setDepthToAtLeast(CurCycle);

  ReleaseSuccessors(SU);
  SU->isScheduled = true;
  AvailableQueue.scheduledNode(SU);
}

/// emitNoop - Add a noop to the current instruction sequence.
void SchedulePostRATDList::emitNoop(unsigned CurCycle) {
  LLVM_DEBUG(dbgs() << "*** Emitting noop in cycle " << CurCycle << '\n');
  HazardRec->EmitNoop();
  Sequence.push_back(nullptr);   // NULL here means noop
  ++NumNoops;
}

/// ListScheduleTopDown - The main loop of list scheduling for top-down
/// schedulers.
void SchedulePostRATDList::ListScheduleTopDown() {
  unsigned CurCycle = 0;

  // We're scheduling top-down but we're visiting the regions in
  // bottom-up order, so we don't know the hazards at the start of a
  // region. So assume no hazards (this should usually be ok as most
  // blocks are a single region).
  HazardRec->Reset();

  // Release any successors of the special Entry node.
  ReleaseSuccessors(&EntrySU);

  // Add all leaves to Available queue.
  for (SUnit &SUnit : SUnits) {
    // It is available if it has no predecessors.
    if (!SUnit.NumPredsLeft && !SUnit.isAvailable) {
      AvailableQueue.push(&SUnit);
      SUnit.isAvailable = true;
    }
  }

  // In any cycle where we can't schedule any instructions, we must
  // stall or emit a noop, depending on the target.
  bool CycleHasInsts = false;

  // While Available queue is not empty, grab the node with the highest
  // priority. If it is not ready put it back.  Schedule the node.
  std::vector<SUnit*> NotReady;
  Sequence.reserve(SUnits.size());
  while (!AvailableQueue.empty() || !PendingQueue.empty()) {
    // Check to see if any of the pending instructions are ready to issue.  If
    // so, add them to the available queue.
    unsigned MinDepth = ~0u;
    for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) {
      if (PendingQueue[i]->getDepth() <= CurCycle) {
        AvailableQueue.push(PendingQueue[i]);
        PendingQueue[i]->isAvailable = true;
        PendingQueue[i] = PendingQueue.back();
        PendingQueue.pop_back();
        --i; --e;
      } else if (PendingQueue[i]->getDepth() < MinDepth)
        MinDepth = PendingQueue[i]->getDepth();
    }

    LLVM_DEBUG(dbgs() << "\n*** Examining Available\n";
               AvailableQueue.dump(this));

    SUnit *FoundSUnit = nullptr, *NotPreferredSUnit = nullptr;
    bool HasNoopHazards = false;
    while (!AvailableQueue.empty()) {
      SUnit *CurSUnit = AvailableQueue.pop();

      ScheduleHazardRecognizer::HazardType HT =
        HazardRec->getHazardType(CurSUnit, 0/*no stalls*/);
      if (HT == ScheduleHazardRecognizer::NoHazard) {
        if (HazardRec->ShouldPreferAnother(CurSUnit)) {
          if (!NotPreferredSUnit) {
            // If this is the first non-preferred node for this cycle, then
            // record it and continue searching for a preferred node. If this
            // is not the first non-preferred node, then treat it as though
            // there had been a hazard.
            NotPreferredSUnit = CurSUnit;
            continue;
          }
        } else {
          FoundSUnit = CurSUnit;
          break;
        }
      }

      // Remember if this is a noop hazard.
      HasNoopHazards |= HT == ScheduleHazardRecognizer::NoopHazard;

      NotReady.push_back(CurSUnit);
    }

    // If we have a non-preferred node, push it back onto the available list.
    // If we did not find a preferred node, then schedule this first
    // non-preferred node.
    if (NotPreferredSUnit) {
      if (!FoundSUnit) {
        LLVM_DEBUG(
            dbgs() << "*** Will schedule a non-preferred instruction...\n");
        FoundSUnit = NotPreferredSUnit;
      } else {
        AvailableQueue.push(NotPreferredSUnit);
      }

      NotPreferredSUnit = nullptr;
    }

    // Add the nodes that aren't ready back onto the available list.
    if (!NotReady.empty()) {
      AvailableQueue.push_all(NotReady);
      NotReady.clear();
    }

    // If we found a node to schedule...
    if (FoundSUnit) {
      // If we need to emit noops prior to this instruction, then do so.
      unsigned NumPreNoops = HazardRec->PreEmitNoops(FoundSUnit);
      for (unsigned i = 0; i != NumPreNoops; ++i)
        emitNoop(CurCycle);

      // ... schedule the node...
      ScheduleNodeTopDown(FoundSUnit, CurCycle);
      HazardRec->EmitInstruction(FoundSUnit);
      CycleHasInsts = true;
      if (HazardRec->atIssueLimit()) {
        LLVM_DEBUG(dbgs() << "*** Max instructions per cycle " << CurCycle
                          << '\n');
        HazardRec->AdvanceCycle();
        ++CurCycle;
        CycleHasInsts = false;
      }
    } else {
      if (CycleHasInsts) {
        LLVM_DEBUG(dbgs() << "*** Finished cycle " << CurCycle << '\n');
        HazardRec->AdvanceCycle();
      } else if (!HasNoopHazards) {
        // Otherwise, we have a pipeline stall, but no other problem,
        // just advance the current cycle and try again.
        LLVM_DEBUG(dbgs() << "*** Stall in cycle " << CurCycle << '\n');
        HazardRec->AdvanceCycle();
        ++NumStalls;
      } else {
        // Otherwise, we have no instructions to issue and we have instructions
        // that will fault if we don't do this right.  This is the case for
        // processors without pipeline interlocks and other cases.
        emitNoop(CurCycle);
      }

      ++CurCycle;
      CycleHasInsts = false;
    }
  }

#ifndef NDEBUG
  unsigned ScheduledNodes = VerifyScheduledDAG(/*isBottomUp=*/false);
  unsigned Noops = llvm::count(Sequence, nullptr);
  assert(Sequence.size() - Noops == ScheduledNodes &&
         "The number of nodes scheduled doesn't match the expected number!");
#endif // NDEBUG
}

// EmitSchedule - Emit the machine code in scheduled order.
void SchedulePostRATDList::EmitSchedule() {
  RegionBegin = RegionEnd;

  // If first instruction was a DBG_VALUE then put it back.
  if (FirstDbgValue)
    BB->splice(RegionEnd, BB, FirstDbgValue);

  // Then re-insert them according to the given schedule.
  for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
    if (SUnit *SU = Sequence[i])
      BB->splice(RegionEnd, BB, SU->getInstr());
    else
      // Null SUnit* is a noop.
      TII->insertNoop(*BB, RegionEnd);

    // Update the Begin iterator, as the first instruction in the block
    // may have been scheduled later.
    if (i == 0)
      RegionBegin = std::prev(RegionEnd);
  }

  // Reinsert any remaining debug_values.
  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 OrigPrivMI = P.second;
    BB->splice(++OrigPrivMI, BB, DbgValue);
  }
  DbgValues.clear();
  FirstDbgValue = nullptr;
}
