misched: Give each ReadyQ a unique ID

llvm-svn: 157428
This commit is contained in:
Andrew Trick 2012-05-24 22:11:12 +00:00
parent 3152745a8f
commit 95b9cef3da

View File

@ -702,23 +702,30 @@ void ScheduleDAGMI::placeDebugValues() {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
namespace { namespace {
/// Wrapper around a vector of SUnits with some basic convenience methods. /// ReadyQ encapsulates vector of "ready" SUnits with basic convenience methods
struct ReadyQueue { /// for pushing and removing nodes. ReadyQ's are uniquely identified by an
typedef std::vector<SUnit*>::iterator iterator; /// ID. SUnit::NodeQueueId us a mask of the ReadyQs that the SUnit is in.
class ReadyQueue {
unsigned ID; unsigned ID;
std::string Name;
std::vector<SUnit*> Queue; std::vector<SUnit*> Queue;
ReadyQueue(unsigned id): ID(id) {} public:
ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
bool isInQueue(SUnit *SU) const { unsigned getID() const { return ID; }
return SU->NodeQueueId & 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(); } bool empty() const { return Queue.empty(); }
unsigned size() const { return Queue.size(); } unsigned size() const { return Queue.size(); }
typedef std::vector<SUnit*>::iterator iterator;
iterator begin() { return Queue.begin(); } iterator begin() { return Queue.begin(); }
iterator end() { return Queue.end(); } iterator end() { return Queue.end(); }
@ -738,7 +745,7 @@ struct ReadyQueue {
Queue.pop_back(); Queue.pop_back();
} }
void dump(const char* Name) { void dump() {
dbgs() << Name << ": "; dbgs() << Name << ": ";
for (unsigned i = 0, e = Queue.size(); i < e; ++i) for (unsigned i = 0, e = Queue.size(); i < e; ++i)
dbgs() << Queue[i]->NodeNum << " "; dbgs() << Queue[i]->NodeNum << " ";
@ -765,6 +772,9 @@ class ConvergingScheduler : public MachineSchedStrategy {
enum CandResult { enum CandResult {
NoCand, NodeOrder, SingleExcess, SingleCritical, SingleMax, MultiPressure }; NoCand, NodeOrder, SingleExcess, SingleCritical, SingleMax, MultiPressure };
/// Each Scheduling boundary is associated with ready queues. It tracks the
/// current cycle in whichever direction at has moved, and maintains the state
/// of "hazards" and other interlocks at the current cycle.
struct SchedBoundary { struct SchedBoundary {
ReadyQueue Available; ReadyQueue Available;
ReadyQueue Pending; ReadyQueue Pending;
@ -778,14 +788,19 @@ class ConvergingScheduler : public MachineSchedStrategy {
/// MinReadyCycle - Cycle of the soonest available instruction. /// MinReadyCycle - Cycle of the soonest available instruction.
unsigned MinReadyCycle; unsigned MinReadyCycle;
/// Pending queues extend the ready queues with the same ID. /// Pending queues extend the ready queues with the same ID and the
SchedBoundary(unsigned ID): /// PendingFlag set.
Available(ID), Pending(ID), CheckPending(false), HazardRec(0), SchedBoundary(unsigned ID, const Twine &Name):
CurrCycle(0), IssueCount(0), MinReadyCycle(UINT_MAX) {} Available(ID, Name+".A"),
Pending(ID << ConvergingScheduler::LogMaxQID, Name+".P"),
CheckPending(false), HazardRec(0), CurrCycle(0), IssueCount(0),
MinReadyCycle(UINT_MAX) {}
~SchedBoundary() { delete HazardRec; } ~SchedBoundary() { delete HazardRec; }
bool isTop() const { return Available.ID == ConvergingScheduler::TopQID; } bool isTop() const {
return Available.getID() == ConvergingScheduler::TopQID;
}
void releaseNode(SUnit *SU, unsigned ReadyCycle); void releaseNode(SUnit *SU, unsigned ReadyCycle);
@ -806,21 +821,15 @@ class ConvergingScheduler : public MachineSchedStrategy {
SchedBoundary Bot; SchedBoundary Bot;
public: public:
/// SUnit::NodeQueueId = 0 (none), = 1 (top), = 2 (bottom), = 3 (both) /// SUnit::NodeQueueId: 0 (none), 1 (top), 2 (bot), 3 (both)
enum { enum {
TopQID = 1, TopQID = 1,
BotQID = 2 BotQID = 2,
LogMaxQID = 2
}; };
ConvergingScheduler(): DAG(0), TRI(0), Top(TopQID), Bot(BotQID) {} ConvergingScheduler():
DAG(0), TRI(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
static const char *getQName(unsigned ID) {
switch(ID) {
default: return "NoQ";
case TopQID: return "TopQ";
case BotQID: return "BotQ";
};
}
virtual void initialize(ScheduleDAGMI *dag); virtual void initialize(ScheduleDAGMI *dag);
@ -839,7 +848,7 @@ protected:
const RegPressureTracker &RPTracker, const RegPressureTracker &RPTracker,
SchedCandidate &Candidate); SchedCandidate &Candidate);
#ifndef NDEBUG #ifndef NDEBUG
void traceCandidate(const char *Label, unsigned QID, SUnit *SU, void traceCandidate(const char *Label, const ReadyQueue &Q, SUnit *SU,
PressureElement P = PressureElement()); PressureElement P = PressureElement());
#endif #endif
}; };
@ -905,7 +914,7 @@ void ConvergingScheduler::SchedBoundary::bumpCycle() {
} }
CheckPending = true; CheckPending = true;
DEBUG(dbgs() << "*** " << getQName(Available.ID) << " cycle " DEBUG(dbgs() << "*** " << Available.getName() << " cycle "
<< CurrCycle << '\n'); << CurrCycle << '\n');
} }
@ -967,9 +976,9 @@ SUnit *ConvergingScheduler::SchedBoundary::pickOnlyChoice() {
} }
#ifndef NDEBUG #ifndef NDEBUG
void ConvergingScheduler::traceCandidate(const char *Label, unsigned QID, void ConvergingScheduler::traceCandidate(const char *Label, const ReadyQueue &Q,
SUnit *SU, PressureElement P) { SUnit *SU, PressureElement P) {
dbgs() << Label << " " << getQName(QID) << " "; dbgs() << Label << " " << Q.getName() << " ";
if (P.isValid()) if (P.isValid())
dbgs() << TRI->getRegPressureSetName(P.PSetID) << ":" << P.UnitIncrease dbgs() << TRI->getRegPressureSetName(P.PSetID) << ":" << P.UnitIncrease
<< " "; << " ";
@ -1010,7 +1019,7 @@ static bool compareRPDelta(const RegPressureDelta &LHS,
ConvergingScheduler::CandResult ConvergingScheduler:: ConvergingScheduler::CandResult ConvergingScheduler::
pickNodeFromQueue(ReadyQueue &Q, const RegPressureTracker &RPTracker, pickNodeFromQueue(ReadyQueue &Q, const RegPressureTracker &RPTracker,
SchedCandidate &Candidate) { SchedCandidate &Candidate) {
DEBUG(Q.dump(getQName(Q.ID))); DEBUG(Q.dump());
// getMaxPressureDelta temporarily modifies the tracker. // getMaxPressureDelta temporarily modifies the tracker.
RegPressureTracker &TempTracker = const_cast<RegPressureTracker&>(RPTracker); RegPressureTracker &TempTracker = const_cast<RegPressureTracker&>(RPTracker);
@ -1032,7 +1041,7 @@ pickNodeFromQueue(ReadyQueue &Q, const RegPressureTracker &RPTracker,
} }
// Avoid exceeding the target's limit. // Avoid exceeding the target's limit.
if (RPDelta.Excess.UnitIncrease < Candidate.RPDelta.Excess.UnitIncrease) { if (RPDelta.Excess.UnitIncrease < Candidate.RPDelta.Excess.UnitIncrease) {
DEBUG(traceCandidate("ECAND", Q.ID, *I, RPDelta.Excess)); DEBUG(traceCandidate("ECAND", Q, *I, RPDelta.Excess));
Candidate.SU = *I; Candidate.SU = *I;
Candidate.RPDelta = RPDelta; Candidate.RPDelta = RPDelta;
FoundCandidate = SingleExcess; FoundCandidate = SingleExcess;
@ -1046,7 +1055,7 @@ pickNodeFromQueue(ReadyQueue &Q, const RegPressureTracker &RPTracker,
// Avoid increasing the max critical pressure in the scheduled region. // Avoid increasing the max critical pressure in the scheduled region.
if (RPDelta.CriticalMax.UnitIncrease if (RPDelta.CriticalMax.UnitIncrease
< Candidate.RPDelta.CriticalMax.UnitIncrease) { < Candidate.RPDelta.CriticalMax.UnitIncrease) {
DEBUG(traceCandidate("PCAND", Q.ID, *I, RPDelta.CriticalMax)); DEBUG(traceCandidate("PCAND", Q, *I, RPDelta.CriticalMax));
Candidate.SU = *I; Candidate.SU = *I;
Candidate.RPDelta = RPDelta; Candidate.RPDelta = RPDelta;
FoundCandidate = SingleCritical; FoundCandidate = SingleCritical;
@ -1061,7 +1070,7 @@ pickNodeFromQueue(ReadyQueue &Q, const RegPressureTracker &RPTracker,
// Avoid increasing the max pressure of the entire region. // Avoid increasing the max pressure of the entire region.
if (RPDelta.CurrentMax.UnitIncrease if (RPDelta.CurrentMax.UnitIncrease
< Candidate.RPDelta.CurrentMax.UnitIncrease) { < Candidate.RPDelta.CurrentMax.UnitIncrease) {
DEBUG(traceCandidate("MCAND", Q.ID, *I, RPDelta.CurrentMax)); DEBUG(traceCandidate("MCAND", Q, *I, RPDelta.CurrentMax));
Candidate.SU = *I; Candidate.SU = *I;
Candidate.RPDelta = RPDelta; Candidate.RPDelta = RPDelta;
FoundCandidate = SingleMax; FoundCandidate = SingleMax;
@ -1078,9 +1087,9 @@ pickNodeFromQueue(ReadyQueue &Q, const RegPressureTracker &RPTracker,
if (FoundCandidate == NoCand) if (FoundCandidate == NoCand)
continue; continue;
if ((Q.ID == TopQID && (*I)->NodeNum < Candidate.SU->NodeNum) if ((Q.getID() == TopQID && (*I)->NodeNum < Candidate.SU->NodeNum)
|| (Q.ID == BotQID && (*I)->NodeNum > Candidate.SU->NodeNum)) { || (Q.getID() == BotQID && (*I)->NodeNum > Candidate.SU->NodeNum)) {
DEBUG(traceCandidate("NCAND", Q.ID, *I)); DEBUG(traceCandidate("NCAND", Q, *I));
Candidate.SU = *I; Candidate.SU = *I;
Candidate.RPDelta = RPDelta; Candidate.RPDelta = RPDelta;
FoundCandidate = NodeOrder; FoundCandidate = NodeOrder;