[llvm-commits] [llvm] r163580 - in /llvm/trunk: include/llvm/CodeGen/MachineScheduler.h lib/CodeGen/MachineScheduler.cpp lib/Target/Hexagon/HexagonMachineScheduler.cpp lib/Target/Hexagon/HexagonMachineScheduler.h
Sean Silva
silvas at purdue.edu
Mon Sep 10 18:15:39 PDT 2012
+#ifndef NDEBUG
+ void dump();
+#endif
CC'ing Manman to make sure that these dump methods are on his radar
(pertaining to r163339 and the ensuing discussion/changes).
--Sean Silva
On Mon, Sep 10, 2012 at 8:39 PM, Andrew Trick <atrick at apple.com> wrote:
> Author: atrick
> Date: Mon Sep 10 19:39:15 2012
> New Revision: 163580
>
> URL: http://llvm.org/viewvc/llvm-project?rev=163580&view=rev
> Log:
> Reorganize MachineScheduler interfaces and publish them in the header.
>
> The Hexagon target decided to use a lot of functionality from the
> target-independent scheduler. That's fine, and other targets should be
> able to do the same. This reorg and API update makes that easy.
>
> For the record, ScheduleDAGMI was not meant to be subclassed. Instead,
> new scheduling algorithms should be able to implement
> MachineSchedStrategy and be done. But if need be, it's nice to be
> able to extend ScheduleDAGMI, so I also made that easier. The target
> scheduler is somewhat more apt to break that way though.
>
> Modified:
> llvm/trunk/include/llvm/CodeGen/MachineScheduler.h
> llvm/trunk/lib/CodeGen/MachineScheduler.cpp
> llvm/trunk/lib/Target/Hexagon/HexagonMachineScheduler.cpp
> llvm/trunk/lib/Target/Hexagon/HexagonMachineScheduler.h
>
> Modified: llvm/trunk/include/llvm/CodeGen/MachineScheduler.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineScheduler.h?rev=163580&r1=163579&r2=163580&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/MachineScheduler.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/MachineScheduler.h Mon Sep 10 19:39:15 2012
> @@ -28,9 +28,16 @@
> #define MACHINESCHEDULER_H
>
> #include "llvm/CodeGen/MachinePassRegistry.h"
> +#include "llvm/CodeGen/RegisterPressure.h"
> +#include "llvm/CodeGen/ScheduleDAGInstrs.h"
> +#include "llvm/Target/TargetInstrInfo.h"
> +#include "llvm/MC/MCInstrItineraries.h"
>
> namespace llvm {
>
> +extern cl::opt<bool> ForceTopDown;
> +extern cl::opt<bool> ForceBottomUp;
> +
> class AliasAnalysis;
> class LiveIntervals;
> class MachineDominatorTree;
> @@ -93,6 +100,217 @@
> }
> };
>
> +class ScheduleDAGMI;
> +
> +/// MachineSchedStrategy - Interface to the scheduling algorithm used by
> +/// ScheduleDAGMI.
> +class MachineSchedStrategy {
> +public:
> + virtual ~MachineSchedStrategy() {}
> +
> + /// Initialize the strategy after building the DAG for a new region.
> + virtual void initialize(ScheduleDAGMI *DAG) = 0;
> +
> + /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
> + /// schedule the node at the top of the unscheduled region. Otherwise it will
> + /// be scheduled at the bottom.
> + virtual SUnit *pickNode(bool &IsTopNode) = 0;
> +
> + /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an
> + /// instruction and updated scheduled/remaining flags in the DAG nodes.
> + virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
> +
> + /// When all predecessor dependencies have been resolved, free this node for
> + /// top-down scheduling.
> + virtual void releaseTopNode(SUnit *SU) = 0;
> + /// When all successor dependencies have been resolved, free this node for
> + /// bottom-up scheduling.
> + virtual void releaseBottomNode(SUnit *SU) = 0;
> +};
> +
> +/// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
> +/// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
> +/// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
> +///
> +/// This is a convenience class that may be used by implementations of
> +/// MachineSchedStrategy.
> +class ReadyQueue {
> + unsigned ID;
> + std::string Name;
> + std::vector<SUnit*> Queue;
> +
> +public:
> + ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
> +
> + unsigned getID() const { return ID; }
> +
> + StringRef getName() const { return Name; }
> +
> + // SU is in this queue if it's NodeQueueID is a superset of this ID.
> + bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
> +
> + bool empty() const { return Queue.empty(); }
> +
> + unsigned size() const { return Queue.size(); }
> +
> + typedef std::vector<SUnit*>::iterator iterator;
> +
> + iterator begin() { return Queue.begin(); }
> +
> + iterator end() { return Queue.end(); }
> +
> + iterator find(SUnit *SU) {
> + return std::find(Queue.begin(), Queue.end(), SU);
> + }
> +
> + void push(SUnit *SU) {
> + Queue.push_back(SU);
> + SU->NodeQueueId |= ID;
> + }
> +
> + void remove(iterator I) {
> + (*I)->NodeQueueId &= ~ID;
> + *I = Queue.back();
> + Queue.pop_back();
> + }
> +
> +#ifndef NDEBUG
> + void dump();
> +#endif
> +};
> +
> +/// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that schedules
> +/// machine instructions while updating LiveIntervals and tracking regpressure.
> +class ScheduleDAGMI : public ScheduleDAGInstrs {
> +protected:
> + AliasAnalysis *AA;
> + RegisterClassInfo *RegClassInfo;
> + MachineSchedStrategy *SchedImpl;
> +
> + MachineBasicBlock::iterator LiveRegionEnd;
> +
> + /// Register pressure in this region computed by buildSchedGraph.
> + IntervalPressure RegPressure;
> + RegPressureTracker RPTracker;
> +
> + /// List of pressure sets that exceed the target's pressure limit before
> + /// scheduling, listed in increasing set ID order. Each pressure set is paired
> + /// with its max pressure in the currently scheduled regions.
> + std::vector<PressureElement> RegionCriticalPSets;
> +
> + /// The top of the unscheduled zone.
> + MachineBasicBlock::iterator CurrentTop;
> + IntervalPressure TopPressure;
> + RegPressureTracker TopRPTracker;
> +
> + /// The bottom of the unscheduled zone.
> + MachineBasicBlock::iterator CurrentBottom;
> + IntervalPressure BotPressure;
> + RegPressureTracker BotRPTracker;
> +
> +#ifndef NDEBUG
> + /// The number of instructions scheduled so far. Used to cut off the
> + /// scheduler at the point determined by misched-cutoff.
> + unsigned NumInstrsScheduled;
> +#endif
> +
> +public:
> + ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S):
> + ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
> + AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S),
> + RPTracker(RegPressure), CurrentTop(), TopRPTracker(TopPressure),
> + CurrentBottom(), BotRPTracker(BotPressure) {
> +#ifndef NDEBUG
> + NumInstrsScheduled = 0;
> +#endif
> + }
> +
> + virtual ~ScheduleDAGMI() {
> + delete SchedImpl;
> + }
> +
> + MachineBasicBlock::iterator top() const { return CurrentTop; }
> + MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
> +
> + /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
> + /// region. This covers all instructions in a block, while schedule() may only
> + /// cover a subset.
> + void enterRegion(MachineBasicBlock *bb,
> + MachineBasicBlock::iterator begin,
> + MachineBasicBlock::iterator end,
> + unsigned endcount);
> +
> +
> + /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
> + /// reorderable instructions.
> + virtual void schedule();
> +
> + /// Get current register pressure for the top scheduled instructions.
> + const IntervalPressure &getTopPressure() const { return TopPressure; }
> + const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
> +
> + /// Get current register pressure for the bottom scheduled instructions.
> + const IntervalPressure &getBotPressure() const { return BotPressure; }
> + const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; }
> +
> + /// Get register pressure for the entire scheduling region before scheduling.
> + const IntervalPressure &getRegPressure() const { return RegPressure; }
> +
> + const std::vector<PressureElement> &getRegionCriticalPSets() const {
> + return RegionCriticalPSets;
> + }
> +
> + /// getIssueWidth - Return the max instructions per scheduling group.
> + unsigned getIssueWidth() const {
> + return (InstrItins && InstrItins->SchedModel)
> + ? InstrItins->SchedModel->IssueWidth : 1;
> + }
> +
> + /// getNumMicroOps - Return the number of issue slots required for this MI.
> + unsigned getNumMicroOps(MachineInstr *MI) const {
> + if (!InstrItins) return 1;
> + int UOps = InstrItins->getNumMicroOps(MI->getDesc().getSchedClass());
> + return (UOps >= 0) ? UOps : TII->getNumMicroOps(InstrItins, MI);
> + }
> +
> +protected:
> + // Top-Level entry points for the schedule() driver...
> +
> + /// Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracking
> + /// enabled. This sets up three trackers. RPTracker will cover the entire DAG
> + /// region, TopTracker and BottomTracker will be initialized to the top and
> + /// bottom of the DAG region without covereing any unscheduled instruction.
> + void buildDAGWithRegPressure();
> +
> + /// Identify DAG roots and setup scheduler queues.
> + void initQueues();
> +
> + /// Move an instruction and update register pressure.
> + void scheduleMI(SUnit *SU, bool IsTopNode);
> +
> + /// Update scheduler DAG and queues after scheduling an instruction.
> + void updateQueues(SUnit *SU, bool IsTopNode);
> +
> + /// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
> + void placeDebugValues();
> +
> + // Lesser helpers...
> +
> + void initRegPressure();
> +
> + void updateScheduledPressure(std::vector<unsigned> NewMaxPressure);
> +
> + void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
> + bool checkSchedLimit();
> +
> + void releaseRoots();
> +
> + void releaseSucc(SUnit *SU, SDep *SuccEdge);
> + void releaseSuccessors(SUnit *SU);
> + void releasePred(SUnit *SU, SDep *PredEdge);
> + void releasePredecessors(SUnit *SU);
> +};
> +
> } // namespace llvm
>
> #endif
>
> Modified: llvm/trunk/lib/CodeGen/MachineScheduler.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineScheduler.cpp?rev=163580&r1=163579&r2=163580&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/MachineScheduler.cpp (original)
> +++ llvm/trunk/lib/CodeGen/MachineScheduler.cpp Mon Sep 10 19:39:15 2012
> @@ -18,11 +18,7 @@
> #include "llvm/CodeGen/MachineScheduler.h"
> #include "llvm/CodeGen/Passes.h"
> #include "llvm/CodeGen/RegisterClassInfo.h"
> -#include "llvm/CodeGen/RegisterPressure.h"
> -#include "llvm/CodeGen/ScheduleDAGInstrs.h"
> #include "llvm/CodeGen/ScheduleHazardRecognizer.h"
> -#include "llvm/Target/TargetInstrInfo.h"
> -#include "llvm/MC/MCInstrItineraries.h"
> #include "llvm/Analysis/AliasAnalysis.h"
> #include "llvm/Support/CommandLine.h"
> #include "llvm/Support/Debug.h"
> @@ -35,10 +31,12 @@
>
> using namespace llvm;
>
> -static cl::opt<bool> ForceTopDown("misched-topdown", cl::Hidden,
> - cl::desc("Force top-down list scheduling"));
> -static cl::opt<bool> ForceBottomUp("misched-bottomup", cl::Hidden,
> - cl::desc("Force bottom-up list scheduling"));
> +namespace llvm {
> +cl::opt<bool> ForceTopDown("misched-topdown", cl::Hidden,
> + cl::desc("Force top-down list scheduling"));
> +cl::opt<bool> ForceBottomUp("misched-bottomup", cl::Hidden,
> + cl::desc("Force bottom-up list scheduling"));
> +}
>
> #ifndef NDEBUG
> static cl::opt<bool> ViewMISchedDAGs("view-misched-dags", cl::Hidden,
> @@ -281,157 +279,20 @@
> // unimplemented
> }
>
> -//===----------------------------------------------------------------------===//
> -// MachineSchedStrategy - Interface to a machine scheduling algorithm.
> -//===----------------------------------------------------------------------===//
> -
> -namespace {
> -class ScheduleDAGMI;
> -
> -/// MachineSchedStrategy - Interface used by ScheduleDAGMI to drive the selected
> -/// scheduling algorithm.
> -///
> -/// If this works well and targets wish to reuse ScheduleDAGMI, we may expose it
> -/// in ScheduleDAGInstrs.h
> -class MachineSchedStrategy {
> -public:
> - virtual ~MachineSchedStrategy() {}
> -
> - /// Initialize the strategy after building the DAG for a new region.
> - virtual void initialize(ScheduleDAGMI *DAG) = 0;
> -
> - /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
> - /// schedule the node at the top of the unscheduled region. Otherwise it will
> - /// be scheduled at the bottom.
> - virtual SUnit *pickNode(bool &IsTopNode) = 0;
> -
> - /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled a node.
> - virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
> -
> - /// When all predecessor dependencies have been resolved, free this node for
> - /// top-down scheduling.
> - virtual void releaseTopNode(SUnit *SU) = 0;
> - /// When all successor dependencies have been resolved, free this node for
> - /// bottom-up scheduling.
> - virtual void releaseBottomNode(SUnit *SU) = 0;
> -};
> -} // namespace
> +#ifndef NDEBUG
> +void ReadyQueue::dump() {
> + dbgs() << Name << ": ";
> + for (unsigned i = 0, e = Queue.size(); i < e; ++i)
> + dbgs() << Queue[i]->NodeNum << " ";
> + dbgs() << "\n";
> +}
> +#endif
>
> //===----------------------------------------------------------------------===//
> // ScheduleDAGMI - Base class for MachineInstr scheduling with LiveIntervals
> // preservation.
> //===----------------------------------------------------------------------===//
>
> -namespace {
> -/// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that schedules
> -/// machine instructions while updating LiveIntervals.
> -class ScheduleDAGMI : public ScheduleDAGInstrs {
> - AliasAnalysis *AA;
> - RegisterClassInfo *RegClassInfo;
> - MachineSchedStrategy *SchedImpl;
> -
> - MachineBasicBlock::iterator LiveRegionEnd;
> -
> - /// Register pressure in this region computed by buildSchedGraph.
> - IntervalPressure RegPressure;
> - RegPressureTracker RPTracker;
> -
> - /// List of pressure sets that exceed the target's pressure limit before
> - /// scheduling, listed in increasing set ID order. Each pressure set is paired
> - /// with its max pressure in the currently scheduled regions.
> - std::vector<PressureElement> RegionCriticalPSets;
> -
> - /// The top of the unscheduled zone.
> - MachineBasicBlock::iterator CurrentTop;
> - IntervalPressure TopPressure;
> - RegPressureTracker TopRPTracker;
> -
> - /// The bottom of the unscheduled zone.
> - MachineBasicBlock::iterator CurrentBottom;
> - IntervalPressure BotPressure;
> - RegPressureTracker BotRPTracker;
> -
> -#ifndef NDEBUG
> - /// The number of instructions scheduled so far. Used to cut off the
> - /// scheduler at the point determined by misched-cutoff.
> - unsigned NumInstrsScheduled;
> -#endif
> -public:
> - ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S):
> - ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
> - AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S),
> - RPTracker(RegPressure), CurrentTop(), TopRPTracker(TopPressure),
> - CurrentBottom(), BotRPTracker(BotPressure) {
> -#ifndef NDEBUG
> - NumInstrsScheduled = 0;
> -#endif
> - }
> -
> - ~ScheduleDAGMI() {
> - delete SchedImpl;
> - }
> -
> - MachineBasicBlock::iterator top() const { return CurrentTop; }
> - MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
> -
> - /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
> - /// region. This covers all instructions in a block, while schedule() may only
> - /// cover a subset.
> - void enterRegion(MachineBasicBlock *bb,
> - MachineBasicBlock::iterator begin,
> - MachineBasicBlock::iterator end,
> - unsigned endcount);
> -
> - /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
> - /// reorderable instructions.
> - void schedule();
> -
> - /// Get current register pressure for the top scheduled instructions.
> - const IntervalPressure &getTopPressure() const { return TopPressure; }
> - const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
> -
> - /// Get current register pressure for the bottom scheduled instructions.
> - const IntervalPressure &getBotPressure() const { return BotPressure; }
> - const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; }
> -
> - /// Get register pressure for the entire scheduling region before scheduling.
> - const IntervalPressure &getRegPressure() const { return RegPressure; }
> -
> - const std::vector<PressureElement> &getRegionCriticalPSets() const {
> - return RegionCriticalPSets;
> - }
> -
> - /// getIssueWidth - Return the max instructions per scheduling group.
> - unsigned getIssueWidth() const {
> - return (InstrItins && InstrItins->SchedModel)
> - ? InstrItins->SchedModel->IssueWidth : 1;
> - }
> -
> - /// getNumMicroOps - Return the number of issue slots required for this MI.
> - unsigned getNumMicroOps(MachineInstr *MI) const {
> - if (!InstrItins) return 1;
> - int UOps = InstrItins->getNumMicroOps(MI->getDesc().getSchedClass());
> - return (UOps >= 0) ? UOps : TII->getNumMicroOps(InstrItins, MI);
> - }
> -
> -protected:
> - void initRegPressure();
> - void updateScheduledPressure(std::vector<unsigned> NewMaxPressure);
> -
> - void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
> - bool checkSchedLimit();
> -
> - void releaseRoots();
> -
> - void releaseSucc(SUnit *SU, SDep *SuccEdge);
> - void releaseSuccessors(SUnit *SU);
> - void releasePred(SUnit *SU, SDep *PredEdge);
> - void releasePredecessors(SUnit *SU);
> -
> - void placeDebugValues();
> -};
> -} // namespace
> -
> /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. When
> /// NumPredsLeft reaches zero, release the successor node.
> ///
> @@ -565,6 +426,9 @@
> std::vector<unsigned> RegionPressure = RPTracker.getPressure().MaxSetPressure;
> for (unsigned i = 0, e = RegionPressure.size(); i < e; ++i) {
> unsigned Limit = TRI->getRegPressureSetLimit(i);
> + DEBUG(dbgs() << TRI->getRegPressureSetName(i)
> + << "Limit " << Limit
> + << " Actual " << RegionPressure[i] << "\n");
> if (RegionPressure[i] > Limit)
> RegionCriticalPSets.push_back(PressureElement(i, 0));
> }
> @@ -610,7 +474,39 @@
> /// 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 easilly extended by experimental schedulers. Generally,
> +/// implementing MachineSchedStrategy should be sufficient to implement a new
> +/// scheduling algorithm. However, if a scheduler further subclasses
> +/// ScheduleDAGMI then it will want to override this virtual method in order to
> +/// update any specialized state.
> void ScheduleDAGMI::schedule() {
> + buildDAGWithRegPressure();
> +
> + DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
> + SUnits[su].dumpAll(this));
> +
> + if (ViewMISchedDAGs) viewGraph();
> +
> + initQueues();
> +
> + bool IsTopNode = false;
> + while (SUnit *SU = SchedImpl->pickNode(IsTopNode)) {
> + if (!checkSchedLimit())
> + break;
> +
> + scheduleMI(SU, IsTopNode);
> +
> + updateQueues(SU, IsTopNode);
> + }
> + assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone.");
> +
> + placeDebugValues();
> +}
> +
> +/// Build the DAG and setup three register pressure trackers.
> +void ScheduleDAGMI::buildDAGWithRegPressure() {
> // Initialize the register pressure tracker used by buildSchedGraph.
> RPTracker.init(&MF, RegClassInfo, LIS, BB, LiveRegionEnd);
>
> @@ -620,15 +516,15 @@
>
> // Build the DAG, and compute current register pressure.
> buildSchedGraph(AA, &RPTracker);
> + if (ViewMISchedDAGs) viewGraph();
>
> // Initialize top/bottom trackers after computing region pressure.
> initRegPressure();
> +}
>
> - DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
> - SUnits[su].dumpAll(this));
> -
> - if (ViewMISchedDAGs) viewGraph();
> -
> +/// Identify DAG roots and setup scheduler queues.
> +void ScheduleDAGMI::initQueues() {
> + // Initialize the strategy before modifying the DAG.
> SchedImpl->initialize(this);
>
> // Release edges from the special Entry node or to the special Exit node.
> @@ -640,59 +536,60 @@
>
> CurrentTop = nextIfDebug(RegionBegin, RegionEnd);
> CurrentBottom = RegionEnd;
> - bool IsTopNode = false;
> - while (SUnit *SU = SchedImpl->pickNode(IsTopNode)) {
> - if (!checkSchedLimit())
> - break;
> -
> - // 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);
> - }
> +}
>
> - // Update top scheduled pressure.
> - TopRPTracker.advance();
> - assert(TopRPTracker.getPos() == CurrentTop && "out of sync");
> - updateScheduledPressure(TopRPTracker.getPressure().MaxSetPressure);
> +/// Move an instruction and update register pressure.
> +void ScheduleDAGMI::scheduleMI(SUnit *SU, bool IsTopNode) {
> + // Move the instruction to its new location in the instruction stream.
> + MachineInstr *MI = SU->getInstr();
>
> - // Release dependent instructions for scheduling.
> - releaseSuccessors(SU);
> + if (IsTopNode) {
> + assert(SU->isTopReady() && "node still has unscheduled dependencies");
> + if (&*CurrentTop == MI)
> + CurrentTop = nextIfDebug(++CurrentTop, CurrentBottom);
> + else {
> + moveInstruction(MI, CurrentTop);
> + TopRPTracker.setPos(MI);
> }
> +
> + // Update top scheduled pressure.
> + TopRPTracker.advance();
> + assert(TopRPTracker.getPos() == CurrentTop && "out of sync");
> + updateScheduledPressure(TopRPTracker.getPressure().MaxSetPressure);
> + }
> + else {
> + assert(SU->isBottomReady() && "node still has unscheduled dependencies");
> + MachineBasicBlock::iterator priorII =
> + priorNonDebug(CurrentBottom, CurrentTop);
> + if (&*priorII == MI)
> + CurrentBottom = priorII;
> 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;
> + if (&*CurrentTop == MI) {
> + CurrentTop = nextIfDebug(++CurrentTop, priorII);
> + TopRPTracker.setPos(CurrentTop);
> }
> - // Update bottom scheduled pressure.
> - BotRPTracker.recede();
> - assert(BotRPTracker.getPos() == CurrentBottom && "out of sync");
> - updateScheduledPressure(BotRPTracker.getPressure().MaxSetPressure);
> -
> - // Release dependent instructions for scheduling.
> - releasePredecessors(SU);
> + moveInstruction(MI, CurrentBottom);
> + CurrentBottom = MI;
> }
> - SU->isScheduled = true;
> - SchedImpl->schedNode(SU, IsTopNode);
> + // Update bottom scheduled pressure.
> + BotRPTracker.recede();
> + assert(BotRPTracker.getPos() == CurrentBottom && "out of sync");
> + updateScheduledPressure(BotRPTracker.getPressure().MaxSetPressure);
> }
> - assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone.");
> +}
>
> - placeDebugValues();
> +/// 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;
> +
> + // Notify the scheduling strategy after updating the DAG.
> + SchedImpl->schedNode(SU, IsTopNode);
> }
>
> /// Reinsert any remaining debug_values, just like the PostRA scheduler.
> @@ -721,59 +618,6 @@
> //===----------------------------------------------------------------------===//
>
> namespace {
> -/// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
> -/// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
> -/// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
> -class ReadyQueue {
> - unsigned ID;
> - std::string Name;
> - std::vector<SUnit*> Queue;
> -
> -public:
> - ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
> -
> - unsigned getID() const { return ID; }
> -
> - StringRef getName() const { return Name; }
> -
> - // SU is in this queue if it's NodeQueueID is a superset of this ID.
> - bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
> -
> - bool empty() const { return Queue.empty(); }
> -
> - unsigned size() const { return Queue.size(); }
> -
> - typedef std::vector<SUnit*>::iterator iterator;
> -
> - iterator begin() { return Queue.begin(); }
> -
> - iterator end() { return Queue.end(); }
> -
> - iterator find(SUnit *SU) {
> - return std::find(Queue.begin(), Queue.end(), SU);
> - }
> -
> - void push(SUnit *SU) {
> - Queue.push_back(SU);
> - SU->NodeQueueId |= ID;
> - }
> -
> - void remove(iterator I) {
> - (*I)->NodeQueueId &= ~ID;
> - *I = Queue.back();
> - Queue.pop_back();
> - }
> -
> -#ifndef NDEBUG
> - void dump() {
> - dbgs() << Name << ": ";
> - for (unsigned i = 0, e = Queue.size(); i < e; ++i)
> - dbgs() << Queue[i]->NodeNum << " ";
> - dbgs() << "\n";
> - }
> -#endif
> -};
> -
> /// ConvergingScheduler shrinks the unscheduled zone using heuristics to balance
> /// the schedule.
> class ConvergingScheduler : public MachineSchedStrategy {
>
> Modified: llvm/trunk/lib/Target/Hexagon/HexagonMachineScheduler.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonMachineScheduler.cpp?rev=163580&r1=163579&r2=163580&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/HexagonMachineScheduler.cpp (original)
> +++ llvm/trunk/lib/Target/Hexagon/HexagonMachineScheduler.cpp Mon Sep 10 19:39:15 2012
> @@ -20,203 +20,6 @@
>
> using namespace llvm;
>
> -static cl::opt<bool> ForceTopDown("vliw-misched-topdown", cl::Hidden,
> - cl::desc("Force top-down list scheduling"));
> -static cl::opt<bool> ForceBottomUp("vliw-misched-bottomup", cl::Hidden,
> - cl::desc("Force bottom-up list scheduling"));
> -
> -#ifndef NDEBUG
> -static cl::opt<bool> ViewMISchedDAGs("vliw-view-misched-dags", cl::Hidden,
> - cl::desc("Pop up a window to show MISched dags after they are processed"));
> -
> -static cl::opt<unsigned> MISchedCutoff("vliw-misched-cutoff", cl::Hidden,
> - cl::desc("Stop scheduling after N instructions"), cl::init(~0U));
> -#else
> -static bool ViewMISchedDAGs = false;
> -#endif // NDEBUG
> -
> -/// Decrement this iterator until reaching the top or a non-debug instr.
> -static MachineBasicBlock::iterator
> -priorNonDebug(MachineBasicBlock::iterator I, MachineBasicBlock::iterator Beg) {
> - assert(I != Beg && "reached the top of the region, cannot decrement");
> - while (--I != Beg) {
> - if (!I->isDebugValue())
> - break;
> - }
> - return I;
> -}
> -
> -/// If this iterator is a debug value, increment until reaching the End or a
> -/// non-debug instruction.
> -static MachineBasicBlock::iterator
> -nextIfDebug(MachineBasicBlock::iterator I, MachineBasicBlock::iterator End) {
> - for(; I != End; ++I) {
> - if (!I->isDebugValue())
> - break;
> - }
> - return I;
> -}
> -
> -/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. When
> -/// NumPredsLeft reaches zero, release the successor node.
> -///
> -/// FIXME: Adjust SuccSU height based on MinLatency.
> -void VLIWMachineScheduler::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)
> - SchedImpl->releaseTopNode(SuccSU);
> -}
> -
> -/// releaseSuccessors - Call releaseSucc on each of SU's successors.
> -void VLIWMachineScheduler::releaseSuccessors(SUnit *SU) {
> - for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
> - I != E; ++I) {
> - releaseSucc(SU, &*I);
> - }
> -}
> -
> -/// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. When
> -/// NumSuccsLeft reaches zero, release the predecessor node.
> -///
> -/// FIXME: Adjust PredSU height based on MinLatency.
> -void VLIWMachineScheduler::releasePred(SUnit *SU, SDep *PredEdge) {
> - SUnit *PredSU = PredEdge->getSUnit();
> -
> -#ifndef NDEBUG
> - if (PredSU->NumSuccsLeft == 0) {
> - dbgs() << "*** Scheduling failed! ***\n";
> - PredSU->dump(this);
> - dbgs() << " has been released too many times!\n";
> - llvm_unreachable(0);
> - }
> -#endif
> - --PredSU->NumSuccsLeft;
> - if (PredSU->NumSuccsLeft == 0 && PredSU != &EntrySU)
> - SchedImpl->releaseBottomNode(PredSU);
> -}
> -
> -/// releasePredecessors - Call releasePred on each of SU's predecessors.
> -void VLIWMachineScheduler::releasePredecessors(SUnit *SU) {
> - for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
> - I != E; ++I) {
> - releasePred(SU, &*I);
> - }
> -}
> -
> -void VLIWMachineScheduler::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
> - LIS->handleMove(MI);
> -
> - // Recede RegionBegin if an instruction moves above the first.
> - if (RegionBegin == InsertPos)
> - RegionBegin = MI;
> -}
> -
> -bool VLIWMachineScheduler::checkSchedLimit() {
> -#ifndef NDEBUG
> - if (NumInstrsScheduled == MISchedCutoff && MISchedCutoff != ~0U) {
> - CurrentTop = CurrentBottom;
> - return false;
> - }
> - ++NumInstrsScheduled;
> -#endif
> - return true;
> -}
> -
> -/// 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 VLIWMachineScheduler::enterRegion(MachineBasicBlock *bb,
> - MachineBasicBlock::iterator begin,
> - MachineBasicBlock::iterator end,
> - unsigned endcount)
> -{
> - ScheduleDAGInstrs::enterRegion(bb, begin, end, endcount);
> -
> - // For convenience remember the end of the liveness region.
> - LiveRegionEnd =
> - (RegionEnd == bb->end()) ? RegionEnd : llvm::next(RegionEnd);
> -}
> -
> -// Setup the register pressure trackers for the top scheduled top and bottom
> -// scheduled regions.
> -void VLIWMachineScheduler::initRegPressure() {
> - TopRPTracker.init(&MF, RegClassInfo, LIS, BB, RegionBegin);
> - BotRPTracker.init(&MF, RegClassInfo, LIS, BB, LiveRegionEnd);
> -
> - // Close the RPTracker to finalize live ins.
> - RPTracker.closeRegion();
> -
> - DEBUG(RPTracker.getPressure().dump(TRI));
> -
> - // 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();
> -
> - // Account for liveness generated by the region boundary.
> - if (LiveRegionEnd != RegionEnd)
> - BotRPTracker.recede();
> -
> - assert(BotRPTracker.getPos() == RegionEnd && "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();
> - std::vector<unsigned> RegionPressure = RPTracker.getPressure().MaxSetPressure;
> - for (unsigned i = 0, e = RegionPressure.size(); i < e; ++i) {
> - unsigned Limit = TRI->getRegPressureSetLimit(i);
> - DEBUG(dbgs() << TRI->getRegPressureSetName(i)
> - << "Limit " << Limit
> - << " Actual " << RegionPressure[i] << "\n");
> - if (RegionPressure[i] > Limit)
> - RegionCriticalPSets.push_back(PressureElement(i, 0));
> - }
> - DEBUG(dbgs() << "Excess PSets: ";
> - for (unsigned i = 0, e = RegionCriticalPSets.size(); i != e; ++i)
> - dbgs() << TRI->getRegPressureSetName(
> - RegionCriticalPSets[i].PSetID) << " ";
> - dbgs() << "\n");
> -
> - TotalPackets = 0;
> -}
> -
> -// FIXME: When the pressure tracker deals in pressure differences then we won't
> -// iterate over all RegionCriticalPSets[i].
> -void VLIWMachineScheduler::
> -updateScheduledPressure(std::vector<unsigned> NewMaxPressure) {
> - for (unsigned i = 0, e = RegionCriticalPSets.size(); i < e; ++i) {
> - unsigned ID = RegionCriticalPSets[i].PSetID;
> - int &MaxUnits = RegionCriticalPSets[i].UnitIncrease;
> - if ((int)NewMaxPressure[ID] > MaxUnits)
> - MaxUnits = NewMaxPressure[ID];
> - }
> -}
> -
> /// Check if scheduling of this SU is possible
> /// in the current packet.
> /// It is _not_ precise (statefull), it is more like
> @@ -312,26 +115,6 @@
> return startNewCycle;
> }
>
> -// Release all DAG roots for scheduling.
> -void VLIWMachineScheduler::releaseRoots() {
> - SmallVector<SUnit*, 16> BotRoots;
> -
> - for (std::vector<SUnit>::iterator
> - I = SUnits.begin(), E = SUnits.end(); I != E; ++I) {
> - // A SUnit is ready to top schedule if it has no predecessors.
> - if (I->Preds.empty())
> - SchedImpl->releaseTopNode(&(*I));
> - // A SUnit is ready to bottom schedule if it has no successors.
> - if (I->Succs.empty())
> - BotRoots.push_back(&(*I));
> - }
> - // 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);
> -}
> -
> /// 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.
> @@ -343,18 +126,7 @@
> << " at loop depth " << MLI->getLoopDepth(BB)
> << " \n");
>
> - // Initialize the register pressure tracker used by buildSchedGraph.
> - RPTracker.init(&MF, RegClassInfo, LIS, BB, LiveRegionEnd);
> -
> - // Account for liveness generate by the region boundary.
> - if (LiveRegionEnd != RegionEnd)
> - RPTracker.recede();
> -
> - // Build the DAG, and compute current register pressure.
> - buildSchedGraph(AA, &RPTracker);
> -
> - // Initialize top/bottom trackers after computing region pressure.
> - initRegPressure();
> + buildDAGWithRegPressure();
>
> // To view Height/Depth correctly, they should be accessed at least once.
> DEBUG(unsigned maxH = 0;
> @@ -370,99 +142,27 @@
> DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
> SUnits[su].dumpAll(this));
>
> - if (ViewMISchedDAGs) viewGraph();
> -
> - SchedImpl->initialize(this);
> + initQueues();
>
> - // Release edges from the special Entry node or to the special Exit node.
> - releaseSuccessors(&EntrySU);
> - releasePredecessors(&ExitSU);
> -
> - // Release all DAG roots for scheduling.
> - releaseRoots();
> -
> - CurrentTop = nextIfDebug(RegionBegin, RegionEnd);
> - CurrentBottom = RegionEnd;
> bool IsTopNode = false;
> while (SUnit *SU = SchedImpl->pickNode(IsTopNode)) {
> if (!checkSchedLimit())
> break;
>
> - // Move the instruction to its new location in the instruction stream.
> - MachineInstr *MI = SU->getInstr();
> + scheduleMI(SU, IsTopNode);
>
> - if (IsTopNode) {
> - assert(SU->isTopReady() && "node still has unscheduled dependencies");
> - if (&*CurrentTop == MI)
> - CurrentTop = nextIfDebug(++CurrentTop, CurrentBottom);
> - else {
> - moveInstruction(MI, CurrentTop);
> - TopRPTracker.setPos(MI);
> - }
> -
> - // Update top scheduled pressure.
> - TopRPTracker.advance();
> - assert(TopRPTracker.getPos() == CurrentTop && "out of sync");
> - updateScheduledPressure(TopRPTracker.getPressure().MaxSetPressure);
> -
> - // Release dependent instructions for scheduling.
> - releaseSuccessors(SU);
> - } 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;
> - }
> - // Update bottom scheduled pressure.
> - BotRPTracker.recede();
> - assert(BotRPTracker.getPos() == CurrentBottom && "out of sync");
> - updateScheduledPressure(BotRPTracker.getPressure().MaxSetPressure);
> -
> - // Release dependent instructions for scheduling.
> - releasePredecessors(SU);
> - }
> - SU->isScheduled = true;
> - SchedImpl->schedNode(SU, IsTopNode);
> + updateQueues(SU, IsTopNode);
> }
> assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone.");
>
> placeDebugValues();
> }
>
> -/// Reinsert any remaining debug_values, just like the PostRA scheduler.
> -void VLIWMachineScheduler::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 = *prior(DI);
> - MachineInstr *DbgValue = P.first;
> - MachineBasicBlock::iterator OrigPrevMI = P.second;
> - BB->splice(++OrigPrevMI, BB, DbgValue);
> - if (OrigPrevMI == llvm::prior(RegionEnd))
> - RegionEnd = DbgValue;
> - }
> - DbgValues.clear();
> - FirstDbgValue = NULL;
> -}
> -
> -void ConvergingVLIWScheduler::initialize(VLIWMachineScheduler *dag) {
> - DAG = dag;
> +void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) {
> + DAG = static_cast<VLIWMachineScheduler*>(dag);
> TRI = DAG->TRI;
> - Top.DAG = dag;
> - Bot.DAG = dag;
> + Top.DAG = DAG;
> + Bot.DAG = DAG;
>
> // Initialize the HazardRecognizers.
> const TargetMachine &TM = DAG->MF.getTarget();
> @@ -473,7 +173,7 @@
> Top.ResourceModel = new VLIWResourceModel(TM);
> Bot.ResourceModel = new VLIWResourceModel(TM);
>
> - assert((!ForceTopDown || !ForceBottomUp) &&
> + assert((!llvm::ForceTopDown || !llvm::ForceBottomUp) &&
> "-misched-topdown incompatible with -misched-bottomup");
> }
>
> @@ -899,7 +599,7 @@
> return NULL;
> }
> SUnit *SU;
> - if (ForceTopDown) {
> + if (llvm::ForceTopDown) {
> SU = Top.pickOnlyChoice();
> if (!SU) {
> SchedCandidate TopCand;
> @@ -910,7 +610,7 @@
> SU = TopCand.SU;
> }
> IsTopNode = true;
> - } else if (ForceBottomUp) {
> + } else if (llvm::ForceBottomUp) {
> SU = Bot.pickOnlyChoice();
> if (!SU) {
> SchedCandidate BotCand;
>
> Modified: llvm/trunk/lib/Target/Hexagon/HexagonMachineScheduler.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonMachineScheduler.h?rev=163580&r1=163579&r2=163580&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/HexagonMachineScheduler.h (original)
> +++ llvm/trunk/lib/Target/Hexagon/HexagonMachineScheduler.h Mon Sep 10 19:39:15 2012
> @@ -33,97 +33,12 @@
>
> using namespace llvm;
>
> -//===----------------------------------------------------------------------===//
> -// MachineSchedStrategy - Interface to a machine scheduling algorithm.
> -//===----------------------------------------------------------------------===//
> -
> namespace llvm {
> -class VLIWMachineScheduler;
> -
> -/// MachineSchedStrategy - Interface used by VLIWMachineScheduler to drive
> -/// the selected scheduling algorithm.
> -///
> -/// TODO: Move this to ScheduleDAGInstrs.h
> -class MachineSchedStrategy {
> -public:
> - virtual ~MachineSchedStrategy() {}
> -
> - /// Initialize the strategy after building the DAG for a new region.
> - virtual void initialize(VLIWMachineScheduler *DAG) = 0;
> -
> - /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
> - /// schedule the node at the top of the unscheduled region. Otherwise it will
> - /// be scheduled at the bottom.
> - virtual SUnit *pickNode(bool &IsTopNode) = 0;
> -
> - /// Notify MachineSchedStrategy that VLIWMachineScheduler has
> - /// scheduled a node.
> - virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
> -
> - /// When all predecessor dependencies have been resolved, free this node for
> - /// top-down scheduling.
> - virtual void releaseTopNode(SUnit *SU) = 0;
> - /// When all successor dependencies have been resolved, free this node for
> - /// bottom-up scheduling.
> - virtual void releaseBottomNode(SUnit *SU) = 0;
> -};
> -
> //===----------------------------------------------------------------------===//
> // ConvergingVLIWScheduler - Implementation of the standard
> // MachineSchedStrategy.
> //===----------------------------------------------------------------------===//
>
> -/// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
> -/// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
> -/// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
> -class ReadyQueue {
> - unsigned ID;
> - std::string Name;
> - std::vector<SUnit*> Queue;
> -
> -public:
> - ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
> -
> - unsigned getID() const { return ID; }
> -
> - StringRef getName() const { return Name; }
> -
> - // SU is in this queue if it's NodeQueueID is a superset of this ID.
> - bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
> -
> - bool empty() const { return Queue.empty(); }
> -
> - unsigned size() const { return Queue.size(); }
> -
> - typedef std::vector<SUnit*>::iterator iterator;
> -
> - iterator begin() { return Queue.begin(); }
> -
> - iterator end() { return Queue.end(); }
> -
> - iterator find(SUnit *SU) {
> - return std::find(Queue.begin(), Queue.end(), SU);
> - }
> -
> - void push(SUnit *SU) {
> - Queue.push_back(SU);
> - SU->NodeQueueId |= ID;
> - }
> -
> - void remove(iterator I) {
> - (*I)->NodeQueueId &= ~ID;
> - *I = Queue.back();
> - Queue.pop_back();
> - }
> -
> - void dump() {
> - dbgs() << Name << ": ";
> - for (unsigned i = 0, e = Queue.size(); i < e; ++i)
> - dbgs() << Queue[i]->NodeNum << " ";
> - dbgs() << "\n";
> - }
> -};
> -
> class VLIWResourceModel {
> /// ResourcesModel - Represents VLIW state.
> /// Not limited to VLIW targets per say, but assumes
> @@ -189,124 +104,17 @@
> unsigned getTotalPackets() const { return TotalPackets; }
> };
>
> -class VLIWMachineScheduler : public ScheduleDAGInstrs {
> - /// AA - AliasAnalysis for making memory reference queries.
> - AliasAnalysis *AA;
> -
> - RegisterClassInfo *RegClassInfo;
> - MachineSchedStrategy *SchedImpl;
> -
> - MachineBasicBlock::iterator LiveRegionEnd;
> -
> - /// Register pressure in this region computed by buildSchedGraph.
> - IntervalPressure RegPressure;
> - RegPressureTracker RPTracker;
> -
> - /// List of pressure sets that exceed the target's pressure limit before
> - /// scheduling, listed in increasing set ID order. Each pressure set is paired
> - /// with its max pressure in the currently scheduled regions.
> - std::vector<PressureElement> RegionCriticalPSets;
> -
> - /// The top of the unscheduled zone.
> - MachineBasicBlock::iterator CurrentTop;
> - IntervalPressure TopPressure;
> - RegPressureTracker TopRPTracker;
> -
> - /// The bottom of the unscheduled zone.
> - MachineBasicBlock::iterator CurrentBottom;
> - IntervalPressure BotPressure;
> - RegPressureTracker BotRPTracker;
> -
> -#ifndef NDEBUG
> - /// The number of instructions scheduled so far. Used to cut off the
> - /// scheduler at the point determined by misched-cutoff.
> - unsigned NumInstrsScheduled;
> -#endif
> -
> - /// Total packets in the region.
> - unsigned TotalPackets;
> -
> +/// Extend the standard ScheduleDAGMI to provide more context and override the
> +/// top-level schedule() driver.
> +class VLIWMachineScheduler : public ScheduleDAGMI {
> const MachineLoopInfo *MLI;
> public:
> VLIWMachineScheduler(MachineSchedContext *C, MachineSchedStrategy *S):
> - ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
> - AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S),
> - RPTracker(RegPressure), CurrentTop(), TopRPTracker(TopPressure),
> - CurrentBottom(), BotRPTracker(BotPressure), MLI(C->MLI) {
> -#ifndef NDEBUG
> - NumInstrsScheduled = 0;
> -#endif
> - TotalPackets = 0;
> - }
> -
> - virtual ~VLIWMachineScheduler() {
> - delete SchedImpl;
> - }
> -
> - MachineBasicBlock::iterator top() const { return CurrentTop; }
> - MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
> -
> - /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
> - /// region. This covers all instructions in a block, while schedule() may only
> - /// cover a subset.
> - void enterRegion(MachineBasicBlock *bb,
> - MachineBasicBlock::iterator begin,
> - MachineBasicBlock::iterator end,
> - unsigned endcount);
> + ScheduleDAGMI(C, S), MLI(C->MLI) {}
>
> /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
> /// time to do some work.
> - void schedule();
> -
> - unsigned CurCycle;
> -
> - /// Get current register pressure for the top scheduled instructions.
> - const IntervalPressure &getTopPressure() const { return TopPressure; }
> - const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
> -
> - /// Get current register pressure for the bottom scheduled instructions.
> - const IntervalPressure &getBotPressure() const { return BotPressure; }
> - const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; }
> -
> - /// Get register pressure for the entire scheduling region before scheduling.
> - const IntervalPressure &getRegPressure() const { return RegPressure; }
> -
> - const std::vector<PressureElement> &getRegionCriticalPSets() const {
> - return RegionCriticalPSets;
> - }
> -
> - /// getIssueWidth - Return the max instructions per scheduling group.
> - unsigned getIssueWidth() const {
> - return (InstrItins && InstrItins->SchedModel)
> - ? InstrItins->SchedModel->IssueWidth : 1;
> - }
> -
> - /// getNumMicroOps - Return the number of issue slots required for this MI.
> - unsigned getNumMicroOps(MachineInstr *MI) const {
> - return 1;
> - //if (!InstrItins) return 1;
> - //int UOps = InstrItins->getNumMicroOps(MI->getDesc().getSchedClass());
> - //return (UOps >= 0) ? UOps : TII->getNumMicroOps(InstrItins, MI);
> - }
> -
> -private:
> - void scheduleNodeTopDown(SUnit *SU);
> - void listScheduleTopDown();
> -
> - void initRegPressure();
> - void updateScheduledPressure(std::vector<unsigned> NewMaxPressure);
> -
> - void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
> - bool checkSchedLimit();
> -
> - void releaseRoots();
> -
> - void releaseSucc(SUnit *SU, SDep *SuccEdge);
> - void releaseSuccessors(SUnit *SU);
> - void releasePred(SUnit *SU, SDep *PredEdge);
> - void releasePredecessors(SUnit *SU);
> -
> - void placeDebugValues();
> + virtual void schedule();
> };
>
> /// ConvergingVLIWScheduler shrinks the unscheduled zone using heuristics
> @@ -405,7 +213,7 @@
> ConvergingVLIWScheduler():
> DAG(0), TRI(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
>
> - virtual void initialize(VLIWMachineScheduler *dag);
> + virtual void initialize(ScheduleDAGMI *dag);
>
> virtual SUnit *pickNode(bool &IsTopNode);
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list