mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-16 16:16:45 +00:00
misched: Give each ReadyQ a unique ID
llvm-svn: 157428
This commit is contained in:
parent
3152745a8f
commit
95b9cef3da
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user