- 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
-
-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 (LPriority2 == RPriority2)
- if (left->CycleBound > right->CycleBound)
- return true;
-
- 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;
- }
-
- 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 {
-/// ScheduleDAGList - List scheduler.
-class ScheduleDAGList : public ScheduleDAG {