+//===----------------------------------------------------------------------===//
+// ScheduleTopeDownLive - Base class for basic top-down scheduling with
+// LiveIntervals preservation.
+// ===----------------------------------------------------------------------===//
+
+namespace {
+/// ScheduleTopDownLive is an implementation of ScheduleDAGInstrs that schedules
+/// machine instructions while updating LiveIntervals.
+class ScheduleTopDownLive : public ScheduleDAGInstrs {
+ AliasAnalysis *AA;
+public:
+ ScheduleTopDownLive(MachineSchedContext *C):
+ ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
+ AA(C->AA) {}
+
+ /// ScheduleDAGInstrs interface.
+ void schedule();
+
+ /// Interface implemented by the selected top-down liveinterval scheduler.
+ ///
+ /// Pick the next node to schedule, or return NULL.
+ virtual SUnit *pickNode() = 0;
+
+ /// When all preceeding dependencies have been resolved, free this node for
+ /// scheduling.
+ virtual void releaseNode(SUnit *SU) = 0;
+
+protected:
+ void releaseSucc(SUnit *SU, SDep *SuccEdge);
+ void releaseSuccessors(SUnit *SU);
+};
+} // namespace
+
+/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. When
+/// NumPredsLeft reaches zero, release the successor node.
+void ScheduleTopDownLive::releaseSucc(SUnit *SU, SDep *SuccEdge) {
+ SUnit *SuccSU = SuccEdge->getSUnit();
+
+#ifndef NDEBUG
+ if (SuccSU->NumPredsLeft == 0) {
+ dbgs() << "*** Scheduling failed! ***\n";
+ SuccSU->dump(this);
+ dbgs() << " has been released too many times!\n";
+ llvm_unreachable(0);
+ }
+#endif
+ --SuccSU->NumPredsLeft;
+ if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU)
+ releaseNode(SuccSU);
+}
+
+/// releaseSuccessors - Call releaseSucc on each of SU's successors.
+void ScheduleTopDownLive::releaseSuccessors(SUnit *SU) {
+ for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
+ I != E; ++I) {
+ releaseSucc(SU, &*I);
+ }
+}
+
+/// schedule - This is called back from ScheduleDAGInstrs::Run() when it's
+/// time to do some work.
+void ScheduleTopDownLive::schedule() {
+ buildSchedGraph(AA);
+
+ DEBUG(dbgs() << "********** MI Scheduling **********\n");
+ DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
+ SUnits[su].dumpAll(this));
+
+ if (ViewMISchedDAGs) viewGraph();
+
+ // Release any successors of the special Entry node. It is currently unused,
+ // but we keep up appearances.
+ releaseSuccessors(&EntrySU);
+
+ // Release all DAG roots for scheduling.
+ for (std::vector<SUnit>::iterator I = SUnits.begin(), E = SUnits.end();
+ I != E; ++I) {
+ // A SUnit is ready to schedule if it has no predecessors.
+ if (I->Preds.empty())
+ releaseNode(&(*I));
+ }
+
+ MachineBasicBlock::iterator InsertPos = RegionBegin;
+ while (SUnit *SU = pickNode()) {
+ DEBUG(dbgs() << "*** Scheduling Instruction:\n"; SU->dump(this));
+
+ // Move the instruction to its new location in the instruction stream.
+ MachineInstr *MI = SU->getInstr();
+ if (&*InsertPos == MI)
+ ++InsertPos;
+ else {
+ BB->splice(InsertPos, BB, MI);
+ LIS->handleMove(MI);
+ if (RegionBegin == InsertPos)
+ RegionBegin = MI;
+ }
+
+ // Release dependent instructions for scheduling.
+ releaseSuccessors(SU);
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Placeholder for the default machine instruction scheduler.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class CommonMachineScheduler : public ScheduleDAGInstrs {
+ AliasAnalysis *AA;
+public:
+ CommonMachineScheduler(MachineSchedContext *C):
+ ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
+ AA(C->AA) {}
+
+ /// schedule - This is called back from ScheduleDAGInstrs::Run() when it's
+ /// time to do some work.
+ void schedule();
+};
+} // namespace
+
+/// The common machine scheduler will be used as the default scheduler if the
+/// target does not set a default.
+static ScheduleDAGInstrs *createCommonMachineSched(MachineSchedContext *C) {
+ return new CommonMachineScheduler(C);
+}
+static MachineSchedRegistry
+SchedCommonRegistry("common", "Use the target's default scheduler choice.",
+ createCommonMachineSched);
+
+/// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
+/// time to do some work.
+void CommonMachineScheduler::schedule() {
+ buildSchedGraph(AA);
+
+ DEBUG(dbgs() << "********** MI Scheduling **********\n");
+ DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
+ SUnits[su].dumpAll(this));
+
+ // TODO: Put interesting things here.
+ //
+ // When this is fully implemented, it will become a subclass of
+ // ScheduleTopDownLive. So this driver will disappear.
+}
+