[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp
Chris Lattner
lattner at cs.uiuc.edu
Tue Mar 7 21:18:39 PST 2006
Changes in directory llvm/lib/CodeGen/SelectionDAG:
ScheduleDAGList.cpp updated: 1.24 -> 1.25
---
Log message:
Split the priority function computation and priority queue management out
of the ScheduleDAGList class into a new SchedulingPriorityQueue class.
---
Diffs of the changes: (+152 -115)
ScheduleDAGList.cpp | 267 +++++++++++++++++++++++++++++-----------------------
1 files changed, 152 insertions(+), 115 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.24 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.25
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.24 Tue Mar 7 22:54:34 2006
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Tue Mar 7 23:18:27 2006
@@ -48,18 +48,17 @@
short NumSuccsLeft; // # of succs not scheduled.
short NumChainPredsLeft; // # of chain preds not scheduled.
short NumChainSuccsLeft; // # of chain succs not scheduled.
- int SethiUllman; // Sethi Ullman number.
bool isTwoAddress : 1; // Is a two-address instruction.
bool isDefNUseOperand : 1; // Is a def&use operand.
unsigned short Latency; // Node latency.
unsigned CycleBound; // Upper/lower cycle to be scheduled at.
+ unsigned NodeNum; // Entry # of node in the node vector.
- SUnit(SDNode *node)
+ SUnit(SDNode *node, unsigned nodenum)
: Node(node), NumPredsLeft(0), NumSuccsLeft(0),
NumChainPredsLeft(0), NumChainSuccsLeft(0),
- SethiUllman(INT_MIN),
isTwoAddress(false), isDefNUseOperand(false),
- Latency(0), CycleBound(0) {}
+ Latency(0), CycleBound(0), NodeNum(nodenum) {}
void dump(const SelectionDAG *G, bool All=true) const;
};
@@ -83,7 +82,6 @@
std::cerr << " # chain preds left : " << NumChainPredsLeft << "\n";
std::cerr << " # chain succs left : " << NumChainSuccsLeft << "\n";
std::cerr << " Latency : " << Latency << "\n";
- std::cerr << " SethiUllman : " << SethiUllman << "\n";
if (Preds.size() != 0) {
std::cerr << " Predecessors:\n";
@@ -121,44 +119,137 @@
}
namespace {
-/// Sorting functions for the Available queue.
-struct ls_rr_sort : public std::binary_function<SUnit*, SUnit*, bool> {
- bool operator()(const SUnit* left, const SUnit* right) const {
- int LBonus = (int)left ->isDefNUseOperand;
- int RBonus = (int)right->isDefNUseOperand;
-
- // Special tie breaker: if two nodes share a operand, the one that
- // use it as a def&use operand is preferred.
- if (left->isTwoAddress && !right->isTwoAddress) {
- SDNode *DUNode = left->Node->getOperand(0).Val;
- if (DUNode->isOperand(right->Node))
- LBonus++;
- }
- if (!left->isTwoAddress && right->isTwoAddress) {
- SDNode *DUNode = right->Node->getOperand(0).Val;
- if (DUNode->isOperand(left->Node))
- RBonus++;
- }
-
- // Priority1 is just the number of live range genned.
- int LPriority1 = left ->NumPredsLeft - LBonus;
- int RPriority1 = right->NumPredsLeft - RBonus;
- int LPriority2 = left ->SethiUllman + LBonus;
- int RPriority2 = right->SethiUllman + RBonus;
+ class SchedulingPriorityQueue;
+
+ /// Sorting functions for the Available queue.
+ struct ls_rr_sort : public std::binary_function<SUnit*, SUnit*, bool> {
+ SchedulingPriorityQueue *SPQ;
+ ls_rr_sort(SchedulingPriorityQueue *spq) : SPQ(spq) {}
+ ls_rr_sort(const ls_rr_sort &RHS) : SPQ(RHS.SPQ) {}
+
+ bool operator()(const SUnit* left, const SUnit* right) const;
+ };
+} // end anonymous namespace
- if (LPriority1 > RPriority1)
+namespace {
+ class SchedulingPriorityQueue {
+ // SUnits - The SUnits for the current graph.
+ std::vector<SUnit> &SUnits;
+
+ // SethiUllmanNumbers - The SethiUllman number for each node.
+ std::vector<int> SethiUllmanNumbers;
+
+ std::priority_queue<SUnit*, std::vector<SUnit*>, ls_rr_sort> Queue;
+ public:
+ SchedulingPriorityQueue(std::vector<SUnit> &sunits)
+ : SUnits(sunits), Queue(ls_rr_sort(this)) {
+ // Calculate node priorities.
+ CalculatePriorities();
+ }
+
+ unsigned getSethiUllmanNumber(unsigned NodeNum) const {
+ assert(NodeNum < SethiUllmanNumbers.size());
+ return SethiUllmanNumbers[NodeNum];
+ }
+
+ bool empty() const { return Queue.empty(); }
+
+ void push(SUnit *U) {
+ Queue.push(U);
+ }
+ SUnit *pop() {
+ SUnit *V = Queue.top();
+ Queue.pop();
+ return V;
+ }
+ private:
+ void CalculatePriorities();
+ int CalcNodePriority(SUnit *SU);
+ };
+}
+
+bool ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
+ unsigned LeftNum = left->NodeNum;
+ unsigned RightNum = right->NodeNum;
+
+ int LBonus = (int)left ->isDefNUseOperand;
+ int RBonus = (int)right->isDefNUseOperand;
+
+ // Special tie breaker: if two nodes share a operand, the one that
+ // use it as a def&use operand is preferred.
+ if (left->isTwoAddress && !right->isTwoAddress) {
+ SDNode *DUNode = left->Node->getOperand(0).Val;
+ if (DUNode->isOperand(right->Node))
+ LBonus++;
+ }
+ if (!left->isTwoAddress && right->isTwoAddress) {
+ SDNode *DUNode = right->Node->getOperand(0).Val;
+ if (DUNode->isOperand(left->Node))
+ RBonus++;
+ }
+
+ // Priority1 is just the number of live range genned.
+ int LPriority1 = left ->NumPredsLeft - LBonus;
+ int RPriority1 = right->NumPredsLeft - RBonus;
+ int LPriority2 = SPQ->getSethiUllmanNumber(LeftNum) + LBonus;
+ int RPriority2 = SPQ->getSethiUllmanNumber(RightNum) + RBonus;
+
+ if (LPriority1 > RPriority1)
+ return true;
+ else if (LPriority1 == RPriority1)
+ if (LPriority2 < RPriority2)
return true;
- else if (LPriority1 == RPriority1)
- if (LPriority2 < RPriority2)
+ else if (LPriority2 == RPriority2)
+ if (left->CycleBound > right->CycleBound)
return true;
- else if (LPriority2 == RPriority2)
- if (left->CycleBound > right->CycleBound)
- return true;
+
+ return false;
+}
+
- return false;
+/// CalcNodePriority - Priority is the Sethi Ullman number.
+/// Smaller number is the higher priority.
+int SchedulingPriorityQueue::CalcNodePriority(SUnit *SU) {
+ int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum];
+ if (SethiUllmanNumber != INT_MIN)
+ return SethiUllmanNumber;
+
+ if (SU->Preds.size() == 0) {
+ SethiUllmanNumber = 1;
+ } else {
+ int Extra = 0;
+ for (std::set<SUnit*>::iterator I = SU->Preds.begin(),
+ E = SU->Preds.end(); I != E; ++I) {
+ SUnit *PredSU = *I;
+ int PredSethiUllman = CalcNodePriority(PredSU);
+ if (PredSethiUllman > SethiUllmanNumber) {
+ SethiUllmanNumber = PredSethiUllman;
+ Extra = 0;
+ } else if (PredSethiUllman == SethiUllmanNumber)
+ Extra++;
+ }
+
+ if (SU->Node->getOpcode() != ISD::TokenFactor)
+ SethiUllmanNumber += Extra;
+ else
+ SethiUllmanNumber = (Extra == 1) ? 0 : Extra-1;
}
-};
-} // end anonymous namespace
+
+ return SethiUllmanNumber;
+}
+
+/// CalculatePriorities - Calculate priorities of all scheduling units.
+void SchedulingPriorityQueue::CalculatePriorities() {
+ SethiUllmanNumbers.assign(SUnits.size(), INT_MIN);
+
+ for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
+ // FIXME: assumes uniform latency for now.
+ SUnits[i].Latency = 1;
+ (void)CalcNodePriority(&SUnits[i]);
+ }
+}
+
+
namespace {
@@ -182,9 +273,6 @@
/// HazardRec - The hazard recognizer to use.
HazardRecognizer *HazardRec;
- typedef std::priority_queue<SUnit*, std::vector<SUnit*>, ls_rr_sort>
- AvailableQueueTy;
-
public:
ScheduleDAGList(SelectionDAG &dag, MachineBasicBlock *bb,
const TargetMachine &tm, bool isbottomup,
@@ -203,14 +291,14 @@
private:
SUnit *NewSUnit(SDNode *N);
- void ReleasePred(AvailableQueueTy &Avail,SUnit *PredSU, bool isChain = false);
- void ReleaseSucc(AvailableQueueTy &Avail,SUnit *SuccSU, bool isChain = false);
- void ScheduleNodeBottomUp(AvailableQueueTy &Avail, SUnit *SU);
- void ScheduleNodeTopDown(AvailableQueueTy &Avail, SUnit *SU);
- int CalcNodePriority(SUnit *SU);
- void CalculatePriorities();
- void ListScheduleTopDown();
- void ListScheduleBottomUp();
+ void ReleasePred(SchedulingPriorityQueue &Avail,
+ SUnit *PredSU, bool isChain = false);
+ void ReleaseSucc(SchedulingPriorityQueue &Avail,
+ SUnit *SuccSU, bool isChain = false);
+ void ScheduleNodeBottomUp(SchedulingPriorityQueue &Avail, SUnit *SU);
+ void ScheduleNodeTopDown(SchedulingPriorityQueue &Avail, SUnit *SU);
+ void ListScheduleTopDown(SchedulingPriorityQueue &Available);
+ void ListScheduleBottomUp(SchedulingPriorityQueue &Available);
void BuildSchedUnits();
void EmitSchedule();
};
@@ -221,13 +309,13 @@
/// NewSUnit - Creates a new SUnit and return a ptr to it.
SUnit *ScheduleDAGList::NewSUnit(SDNode *N) {
- SUnits.push_back(N);
+ SUnits.push_back(SUnit(N, SUnits.size()));
return &SUnits.back();
}
/// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to
/// the Available queue is the count reaches zero. Also update its cycle bound.
-void ScheduleDAGList::ReleasePred(AvailableQueueTy &Available,
+void ScheduleDAGList::ReleasePred(SchedulingPriorityQueue &Available,
SUnit *PredSU, bool isChain) {
// FIXME: the distance between two nodes is not always == the predecessor's
// latency. For example, the reader can very well read the register written
@@ -258,7 +346,7 @@
/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to
/// the Available queue is the count reaches zero. Also update its cycle bound.
-void ScheduleDAGList::ReleaseSucc(AvailableQueueTy &Available,
+void ScheduleDAGList::ReleaseSucc(SchedulingPriorityQueue &Available,
SUnit *SuccSU, bool isChain) {
// FIXME: the distance between two nodes is not always == the predecessor's
// latency. For example, the reader can very well read the register written
@@ -287,7 +375,7 @@
/// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending
/// count of its predecessors. If a predecessor pending count is zero, add it to
/// the Available queue.
-void ScheduleDAGList::ScheduleNodeBottomUp(AvailableQueueTy &Available,
+void ScheduleDAGList::ScheduleNodeBottomUp(SchedulingPriorityQueue &Available,
SUnit *SU) {
DEBUG(std::cerr << "*** Scheduling: ");
DEBUG(SU->dump(&DAG, false));
@@ -310,7 +398,7 @@
/// 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 ScheduleDAGList::ScheduleNodeTopDown(AvailableQueueTy &Available,
+void ScheduleDAGList::ScheduleNodeTopDown(SchedulingPriorityQueue &Available,
SUnit *SU) {
DEBUG(std::cerr << "*** Scheduling: ");
DEBUG(SU->dump(&DAG, false));
@@ -338,10 +426,7 @@
/// ListScheduleBottomUp - The main loop of list scheduling for bottom-up
/// schedulers.
-void ScheduleDAGList::ListScheduleBottomUp() {
- // Available queue.
- AvailableQueueTy Available;
-
+void ScheduleDAGList::ListScheduleBottomUp(SchedulingPriorityQueue &Available) {
// Add root to Available queue.
Available.push(SUnitMap[DAG.getRoot().Val]);
@@ -349,13 +434,11 @@
// priority. If it is not ready put it back. Schedule the node.
std::vector<SUnit*> NotReady;
while (!Available.empty()) {
- SUnit *CurrNode = Available.top();
- Available.pop();
+ SUnit *CurrNode = Available.pop();
while (!isReady(CurrNode, CurrCycle)) {
NotReady.push_back(CurrNode);
- CurrNode = Available.top();
- Available.pop();
+ CurrNode = Available.pop();
}
// Add the nodes that aren't ready back onto the available list.
@@ -395,10 +478,7 @@
/// ListScheduleTopDown - The main loop of list scheduling for top-down
/// schedulers.
-void ScheduleDAGList::ListScheduleTopDown() {
- // Available queue.
- AvailableQueueTy Available;
-
+void ScheduleDAGList::ListScheduleTopDown(SchedulingPriorityQueue &Available) {
// Emit the entry node first.
SUnit *Entry = SUnitMap[DAG.getEntryNode().Val];
ScheduleNodeTopDown(Available, Entry);
@@ -420,8 +500,7 @@
bool HasNoopHazards = false;
do {
- SUnit *CurNode = Available.top();
- Available.pop();
+ SUnit *CurNode = Available.pop();
// Get the node represented by this SUnit.
SDNode *N = CurNode->Node;
@@ -487,47 +566,6 @@
}
-/// CalcNodePriority - Priority is the Sethi Ullman number.
-/// Smaller number is the higher priority.
-int ScheduleDAGList::CalcNodePriority(SUnit *SU) {
- if (SU->SethiUllman != INT_MIN)
- return SU->SethiUllman;
-
- if (SU->Preds.size() == 0) {
- SU->SethiUllman = 1;
- } else {
- int Extra = 0;
- for (std::set<SUnit*>::iterator I = SU->Preds.begin(),
- E = SU->Preds.end(); I != E; ++I) {
- SUnit *PredSU = *I;
- int PredSethiUllman = CalcNodePriority(PredSU);
- if (PredSethiUllman > SU->SethiUllman) {
- SU->SethiUllman = PredSethiUllman;
- Extra = 0;
- } else if (PredSethiUllman == SU->SethiUllman)
- Extra++;
- }
-
- if (SU->Node->getOpcode() != ISD::TokenFactor)
- SU->SethiUllman += Extra;
- else
- SU->SethiUllman = (Extra == 1) ? 0 : Extra-1;
- }
-
- return SU->SethiUllman;
-}
-
-/// CalculatePriorities - Calculate priorities of all scheduling units.
-void ScheduleDAGList::CalculatePriorities() {
- for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
- // FIXME: assumes uniform latency for now.
- SUnits[i].Latency = 1;
- (void)CalcNodePriority(&SUnits[i]);
- DEBUG(SUnits[i].dump(&DAG));
- DEBUG(std::cerr << "\n");
- }
-}
-
void ScheduleDAGList::BuildSchedUnits() {
// Reserve entries in the vector for each of the SUnits we are creating. This
// ensure that reallocation of the vector won't happen, so SUnit*'s won't get
@@ -662,15 +700,14 @@
// Build scheduling units.
BuildSchedUnits();
-
- // Calculate node priorities.
- CalculatePriorities();
-
+
+ SchedulingPriorityQueue PQ(SUnits);
+
// Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate.
if (isBottomUp)
- ListScheduleBottomUp();
+ ListScheduleBottomUp(PQ);
else
- ListScheduleTopDown();
+ ListScheduleTopDown(PQ);
DEBUG(std::cerr << "*** Final schedule ***\n");
DEBUG(dump());
More information about the llvm-commits
mailing list