remove temporary option
[oota-llvm.git] / lib / CodeGen / SelectionDAG / ScheduleDAGList.cpp
1 //===---- ScheduleDAGList.cpp - Implement a list scheduler for isel DAG ---===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Evan Cheng and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This implements bottom-up and top-down list schedulers, using standard
11 // algorithms.  The basic approach uses a priority queue of available nodes to
12 // schedule.  One at a time, nodes are taken from the priority queue (thus in
13 // priority order), checked for legality to schedule, and emitted if legal.
14 //
15 // Nodes may not be legal to schedule either due to structural hazards (e.g.
16 // pipeline or resource constraints) or because an input to the instruction has
17 // not completed execution.
18 //
19 //===----------------------------------------------------------------------===//
20
21 #define DEBUG_TYPE "sched"
22 #include "llvm/CodeGen/ScheduleDAG.h"
23 #include "llvm/Target/TargetMachine.h"
24 #include "llvm/Target/TargetInstrInfo.h"
25 #include "llvm/Support/Debug.h"
26 #include "llvm/ADT/Statistic.h"
27 #include <climits>
28 #include <iostream>
29 #include <queue>
30 #include <set>
31 #include <vector>
32 #include "llvm/Support/CommandLine.h"
33 using namespace llvm;
34
35 namespace {
36   Statistic<> NumNoops ("scheduler", "Number of noops inserted");
37   Statistic<> NumStalls("scheduler", "Number of pipeline stalls");
38
39   /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
40   /// a group of nodes flagged together.
41   struct SUnit {
42     SDNode *Node;                       // Representative node.
43     std::vector<SDNode*> FlaggedNodes;  // All nodes flagged to Node.
44     std::set<SUnit*> Preds;             // All real predecessors.
45     std::set<SUnit*> ChainPreds;        // All chain predecessors.
46     std::set<SUnit*> Succs;             // All real successors.
47     std::set<SUnit*> ChainSuccs;        // All chain successors.
48     short NumPredsLeft;                 // # of preds not scheduled.
49     short NumSuccsLeft;                 // # of succs not scheduled.
50     short NumChainPredsLeft;            // # of chain preds not scheduled.
51     short NumChainSuccsLeft;            // # of chain succs not scheduled.
52     bool isTwoAddress     : 1;          // Is a two-address instruction.
53     bool isDefNUseOperand : 1;          // Is a def&use operand.
54     unsigned short Latency;             // Node latency.
55     unsigned CycleBound;                // Upper/lower cycle to be scheduled at.
56     unsigned NodeNum;                   // Entry # of node in the node vector.
57     
58     SUnit(SDNode *node, unsigned nodenum)
59       : Node(node), NumPredsLeft(0), NumSuccsLeft(0),
60       NumChainPredsLeft(0), NumChainSuccsLeft(0),
61       isTwoAddress(false), isDefNUseOperand(false),
62       Latency(0), CycleBound(0), NodeNum(nodenum) {}
63     
64     void dump(const SelectionDAG *G) const;
65     void dumpAll(const SelectionDAG *G) const;
66   };
67 }
68
69 void SUnit::dump(const SelectionDAG *G) const {
70   std::cerr << "SU: ";
71   Node->dump(G);
72   std::cerr << "\n";
73   if (FlaggedNodes.size() != 0) {
74     for (unsigned i = 0, e = FlaggedNodes.size(); i != e; i++) {
75       std::cerr << "    ";
76       FlaggedNodes[i]->dump(G);
77       std::cerr << "\n";
78     }
79   }
80 }
81
82 void SUnit::dumpAll(const SelectionDAG *G) const {
83   dump(G);
84
85   std::cerr << "  # preds left       : " << NumPredsLeft << "\n";
86   std::cerr << "  # succs left       : " << NumSuccsLeft << "\n";
87   std::cerr << "  # chain preds left : " << NumChainPredsLeft << "\n";
88   std::cerr << "  # chain succs left : " << NumChainSuccsLeft << "\n";
89   std::cerr << "  Latency            : " << Latency << "\n";
90
91   if (Preds.size() != 0) {
92     std::cerr << "  Predecessors:\n";
93     for (std::set<SUnit*>::const_iterator I = Preds.begin(),
94            E = Preds.end(); I != E; ++I) {
95       std::cerr << "    ";
96       (*I)->dump(G);
97     }
98   }
99   if (ChainPreds.size() != 0) {
100     std::cerr << "  Chained Preds:\n";
101     for (std::set<SUnit*>::const_iterator I = ChainPreds.begin(),
102            E = ChainPreds.end(); I != E; ++I) {
103       std::cerr << "    ";
104       (*I)->dump(G);
105     }
106   }
107   if (Succs.size() != 0) {
108     std::cerr << "  Successors:\n";
109     for (std::set<SUnit*>::const_iterator I = Succs.begin(),
110            E = Succs.end(); I != E; ++I) {
111       std::cerr << "    ";
112       (*I)->dump(G);
113     }
114   }
115   if (ChainSuccs.size() != 0) {
116     std::cerr << "  Chained succs:\n";
117     for (std::set<SUnit*>::const_iterator I = ChainSuccs.begin(),
118            E = ChainSuccs.end(); I != E; ++I) {
119       std::cerr << "    ";
120       (*I)->dump(G);
121     }
122   }
123   std::cerr << "\n";
124 }
125
126 //===----------------------------------------------------------------------===//
127 /// SchedulingPriorityQueue - This interface is used to plug different
128 /// priorities computation algorithms into the list scheduler. It implements the
129 /// interface of a standard priority queue, where nodes are inserted in 
130 /// arbitrary order and returned in priority order.  The computation of the
131 /// priority and the representation of the queue are totally up to the
132 /// implementation to decide.
133 /// 
134 namespace {
135 class SchedulingPriorityQueue {
136 public:
137   virtual ~SchedulingPriorityQueue() {}
138   
139   virtual void initNodes(const std::vector<SUnit> &SUnits) = 0;
140   virtual void releaseState() = 0;
141   
142   virtual bool empty() const = 0;
143   virtual void push(SUnit *U) = 0;
144   virtual SUnit *pop() = 0;
145 };
146 }
147
148
149
150 namespace {
151 //===----------------------------------------------------------------------===//
152 /// ScheduleDAGList - The actual list scheduler implementation.  This supports
153 /// both top-down and bottom-up scheduling.
154 ///
155 class ScheduleDAGList : public ScheduleDAG {
156 private:
157   // SDNode to SUnit mapping (many to one).
158   std::map<SDNode*, SUnit*> SUnitMap;
159   // The schedule.  Null SUnit*'s represent noop instructions.
160   std::vector<SUnit*> Sequence;
161   // Current scheduling cycle.
162   unsigned CurrCycle;
163   
164   // The scheduling units.
165   std::vector<SUnit> SUnits;
166
167   /// isBottomUp - This is true if the scheduling problem is bottom-up, false if
168   /// it is top-down.
169   bool isBottomUp;
170   
171   /// PriorityQueue - The priority queue to use.
172   SchedulingPriorityQueue *PriorityQueue;
173   
174   /// HazardRec - The hazard recognizer to use.
175   HazardRecognizer *HazardRec;
176   
177 public:
178   ScheduleDAGList(SelectionDAG &dag, MachineBasicBlock *bb,
179                   const TargetMachine &tm, bool isbottomup,
180                   SchedulingPriorityQueue *priorityqueue,
181                   HazardRecognizer *HR)
182     : ScheduleDAG(listSchedulingBURR, dag, bb, tm),
183       CurrCycle(0), isBottomUp(isbottomup), 
184       PriorityQueue(priorityqueue), HazardRec(HR) {
185     }
186
187   ~ScheduleDAGList() {
188     delete HazardRec;
189     delete PriorityQueue;
190   }
191
192   void Schedule();
193
194   void dumpSchedule() const;
195
196 private:
197   SUnit *NewSUnit(SDNode *N);
198   void ReleasePred(SUnit *PredSU, bool isChain = false);
199   void ReleaseSucc(SUnit *SuccSU, bool isChain = false);
200   void ScheduleNodeBottomUp(SUnit *SU);
201   void ScheduleNodeTopDown(SUnit *SU);
202   void ListScheduleTopDown();
203   void ListScheduleBottomUp();
204   void BuildSchedUnits();
205   void EmitSchedule();
206 };
207 }  // end anonymous namespace
208
209 HazardRecognizer::~HazardRecognizer() {}
210
211
212 /// NewSUnit - Creates a new SUnit and return a ptr to it.
213 SUnit *ScheduleDAGList::NewSUnit(SDNode *N) {
214   SUnits.push_back(SUnit(N, SUnits.size()));
215   return &SUnits.back();
216 }
217
218 /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to
219 /// the Available queue is the count reaches zero. Also update its cycle bound.
220 void ScheduleDAGList::ReleasePred(SUnit *PredSU, bool isChain) {
221   // FIXME: the distance between two nodes is not always == the predecessor's
222   // latency. For example, the reader can very well read the register written
223   // by the predecessor later than the issue cycle. It also depends on the
224   // interrupt model (drain vs. freeze).
225   PredSU->CycleBound = std::max(PredSU->CycleBound,CurrCycle + PredSU->Latency);
226
227   if (!isChain)
228     PredSU->NumSuccsLeft--;
229   else
230     PredSU->NumChainSuccsLeft--;
231   
232 #ifndef NDEBUG
233   if (PredSU->NumSuccsLeft < 0 || PredSU->NumChainSuccsLeft < 0) {
234     std::cerr << "*** List scheduling failed! ***\n";
235     PredSU->dump(&DAG);
236     std::cerr << " has been released too many times!\n";
237     assert(0);
238   }
239 #endif
240   
241   if ((PredSU->NumSuccsLeft + PredSU->NumChainSuccsLeft) == 0) {
242     // EntryToken has to go last!  Special case it here.
243     if (PredSU->Node->getOpcode() != ISD::EntryToken)
244       PriorityQueue->push(PredSU);
245   }
246 }
247
248 /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to
249 /// the Available queue is the count reaches zero. Also update its cycle bound.
250 void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain) {
251   // FIXME: the distance between two nodes is not always == the predecessor's
252   // latency. For example, the reader can very well read the register written
253   // by the predecessor later than the issue cycle. It also depends on the
254   // interrupt model (drain vs. freeze).
255   SuccSU->CycleBound = std::max(SuccSU->CycleBound,CurrCycle + SuccSU->Latency);
256   
257   if (!isChain)
258     SuccSU->NumPredsLeft--;
259   else
260     SuccSU->NumChainPredsLeft--;
261   
262 #ifndef NDEBUG
263   if (SuccSU->NumPredsLeft < 0 || SuccSU->NumChainPredsLeft < 0) {
264     std::cerr << "*** List scheduling failed! ***\n";
265     SuccSU->dump(&DAG);
266     std::cerr << " has been released too many times!\n";
267     abort();
268   }
269 #endif
270   
271   if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0)
272     PriorityQueue->push(SuccSU);
273 }
274
275 /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending
276 /// count of its predecessors. If a predecessor pending count is zero, add it to
277 /// the Available queue.
278 void ScheduleDAGList::ScheduleNodeBottomUp(SUnit *SU) {
279   DEBUG(std::cerr << "*** Scheduling: ");
280   DEBUG(SU->dump(&DAG));
281
282   Sequence.push_back(SU);
283
284   // Bottom up: release predecessors
285   for (std::set<SUnit*>::iterator I1 = SU->Preds.begin(),
286          E1 = SU->Preds.end(); I1 != E1; ++I1) {
287     ReleasePred(*I1);
288     SU->NumPredsLeft--;
289   }
290   for (std::set<SUnit*>::iterator I2 = SU->ChainPreds.begin(),
291          E2 = SU->ChainPreds.end(); I2 != E2; ++I2)
292     ReleasePred(*I2, true);
293
294   CurrCycle++;
295 }
296
297 /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending
298 /// count of its successors. If a successor pending count is zero, add it to
299 /// the Available queue.
300 void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU) {
301   DEBUG(std::cerr << "*** Scheduling: ");
302   DEBUG(SU->dump(&DAG));
303   
304   Sequence.push_back(SU);
305   
306   // Bottom up: release successors.
307   for (std::set<SUnit*>::iterator I1 = SU->Succs.begin(),
308        E1 = SU->Succs.end(); I1 != E1; ++I1) {
309     ReleaseSucc(*I1);
310     SU->NumSuccsLeft--;
311   }
312   for (std::set<SUnit*>::iterator I2 = SU->ChainSuccs.begin(),
313        E2 = SU->ChainSuccs.end(); I2 != E2; ++I2)
314     ReleaseSucc(*I2, true);
315   
316   CurrCycle++;
317 }
318
319 /// isReady - True if node's lower cycle bound is less or equal to the current
320 /// scheduling cycle. Always true if all nodes have uniform latency 1.
321 static inline bool isReady(SUnit *SU, unsigned CurrCycle) {
322   return SU->CycleBound <= CurrCycle;
323 }
324
325 /// ListScheduleBottomUp - The main loop of list scheduling for bottom-up
326 /// schedulers.
327 void ScheduleDAGList::ListScheduleBottomUp() {
328   // Add root to Available queue.
329   PriorityQueue->push(SUnitMap[DAG.getRoot().Val]);
330
331   // While Available queue is not empty, grab the node with the highest
332   // priority. If it is not ready put it back. Schedule the node.
333   std::vector<SUnit*> NotReady;
334   while (!PriorityQueue->empty()) {
335     SUnit *CurrNode = PriorityQueue->pop();
336
337     while (!isReady(CurrNode, CurrCycle)) {
338       NotReady.push_back(CurrNode);
339       CurrNode = PriorityQueue->pop();
340     }
341     
342     // Add the nodes that aren't ready back onto the available list.
343     while (!NotReady.empty()) {
344       PriorityQueue->push(NotReady.back());
345       NotReady.pop_back();
346     }
347
348     ScheduleNodeBottomUp(CurrNode);
349   }
350
351   // Add entry node last
352   if (DAG.getEntryNode().Val != DAG.getRoot().Val) {
353     SUnit *Entry = SUnitMap[DAG.getEntryNode().Val];
354     Sequence.push_back(Entry);
355   }
356
357   // Reverse the order if it is bottom up.
358   std::reverse(Sequence.begin(), Sequence.end());
359   
360   
361 #ifndef NDEBUG
362   // Verify that all SUnits were scheduled.
363   bool AnyNotSched = false;
364   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
365     if (SUnits[i].NumSuccsLeft != 0 || SUnits[i].NumChainSuccsLeft != 0) {
366       if (!AnyNotSched)
367         std::cerr << "*** List scheduling failed! ***\n";
368       SUnits[i].dump(&DAG);
369       std::cerr << "has not been scheduled!\n";
370       AnyNotSched = true;
371     }
372   }
373   assert(!AnyNotSched);
374 #endif
375 }
376
377 /// ListScheduleTopDown - The main loop of list scheduling for top-down
378 /// schedulers.
379 void ScheduleDAGList::ListScheduleTopDown() {
380   // Emit the entry node first.
381   SUnit *Entry = SUnitMap[DAG.getEntryNode().Val];
382   ScheduleNodeTopDown(Entry);
383   HazardRec->EmitInstruction(Entry->Node);
384                       
385   // All leaves to Available queue.
386   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
387     // It is available if it has no predecessors.
388     if ((SUnits[i].Preds.size() + SUnits[i].ChainPreds.size()) == 0 &&
389         &SUnits[i] != Entry)
390       PriorityQueue->push(&SUnits[i]);
391   }
392   
393   // While Available queue is not empty, grab the node with the highest
394   // priority. If it is not ready put it back.  Schedule the node.
395   std::vector<SUnit*> NotReady;
396   while (!PriorityQueue->empty()) {
397     SUnit *FoundNode = 0;
398
399     bool HasNoopHazards = false;
400     do {
401       SUnit *CurNode = PriorityQueue->pop();
402       
403       // Get the node represented by this SUnit.
404       SDNode *N = CurNode->Node;
405       // If this is a pseudo op, like copyfromreg, look to see if there is a
406       // real target node flagged to it.  If so, use the target node.
407       for (unsigned i = 0, e = CurNode->FlaggedNodes.size(); 
408            N->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i)
409         N = CurNode->FlaggedNodes[i];
410       
411       HazardRecognizer::HazardType HT = HazardRec->getHazardType(N);
412       if (HT == HazardRecognizer::NoHazard) {
413         FoundNode = CurNode;
414         break;
415       }
416       
417       // Remember if this is a noop hazard.
418       HasNoopHazards |= HT == HazardRecognizer::NoopHazard;
419       
420       NotReady.push_back(CurNode);
421     } while (!PriorityQueue->empty());
422     
423     // Add the nodes that aren't ready back onto the available list.
424     while (!NotReady.empty()) {
425       PriorityQueue->push(NotReady.back());
426       NotReady.pop_back();
427     }
428
429     // If we found a node to schedule, do it now.
430     if (FoundNode) {
431       ScheduleNodeTopDown(FoundNode);
432       HazardRec->EmitInstruction(FoundNode->Node);
433     } else if (!HasNoopHazards) {
434       // Otherwise, we have a pipeline stall, but no other problem, just advance
435       // the current cycle and try again.
436       DEBUG(std::cerr << "*** Advancing cycle, no work to do\n");
437       HazardRec->AdvanceCycle();
438       ++NumStalls;
439     } else {
440       // Otherwise, we have no instructions to issue and we have instructions
441       // that will fault if we don't do this right.  This is the case for
442       // processors without pipeline interlocks and other cases.
443       DEBUG(std::cerr << "*** Emitting noop\n");
444       HazardRec->EmitNoop();
445       Sequence.push_back(0);   // NULL SUnit* -> noop
446       ++NumNoops;
447     }
448   }
449
450 #ifndef NDEBUG
451   // Verify that all SUnits were scheduled.
452   bool AnyNotSched = false;
453   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
454     if (SUnits[i].NumPredsLeft != 0 || SUnits[i].NumChainPredsLeft != 0) {
455       if (!AnyNotSched)
456         std::cerr << "*** List scheduling failed! ***\n";
457       SUnits[i].dump(&DAG);
458       std::cerr << "has not been scheduled!\n";
459       AnyNotSched = true;
460     }
461   }
462   assert(!AnyNotSched);
463 #endif
464 }
465
466
467 void ScheduleDAGList::BuildSchedUnits() {
468   // Reserve entries in the vector for each of the SUnits we are creating.  This
469   // ensure that reallocation of the vector won't happen, so SUnit*'s won't get
470   // invalidated.
471   SUnits.reserve(NodeCount);
472   
473   const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
474
475   // Pass 1: create the SUnit's.
476   for (unsigned i = 0, NC = NodeCount; i < NC; i++) {
477     NodeInfo *NI = &Info[i];
478     SDNode *N = NI->Node;
479     if (isPassiveNode(N))
480       continue;
481
482     SUnit *SU;
483     if (NI->isInGroup()) {
484       if (NI != NI->Group->getBottom())  // Bottom up, so only look at bottom
485         continue;                        // node of the NodeGroup
486
487       SU = NewSUnit(N);
488       // Find the flagged nodes.
489       SDOperand  FlagOp = N->getOperand(N->getNumOperands() - 1);
490       SDNode    *Flag   = FlagOp.Val;
491       unsigned   ResNo  = FlagOp.ResNo;
492       while (Flag->getValueType(ResNo) == MVT::Flag) {
493         NodeInfo *FNI = getNI(Flag);
494         assert(FNI->Group == NI->Group);
495         SU->FlaggedNodes.insert(SU->FlaggedNodes.begin(), Flag);
496         SUnitMap[Flag] = SU;
497
498         FlagOp = Flag->getOperand(Flag->getNumOperands() - 1);
499         Flag   = FlagOp.Val;
500         ResNo  = FlagOp.ResNo;
501       }
502     } else {
503       SU = NewSUnit(N);
504     }
505     SUnitMap[N] = SU;
506
507     // Compute the latency for the node.  We use the sum of the latencies for
508     // all nodes flagged together into this SUnit.
509     if (InstrItins.isEmpty()) {
510       // No latency information.
511       SU->Latency = 1;
512     } else {
513       SU->Latency = 0;
514       if (N->isTargetOpcode()) {
515         unsigned SchedClass = TII->getSchedClass(N->getTargetOpcode());
516         InstrStage *S = InstrItins.begin(SchedClass);
517         InstrStage *E = InstrItins.end(SchedClass);
518         for (; S != E; ++S)
519           SU->Latency += S->Cycles;
520       }
521       for (unsigned i = 0, e = SU->FlaggedNodes.size(); i != e; ++i) {
522         SDNode *FNode = SU->FlaggedNodes[i];
523         if (FNode->isTargetOpcode()) {
524           unsigned SchedClass = TII->getSchedClass(FNode->getTargetOpcode());
525           InstrStage *S = InstrItins.begin(SchedClass);
526           InstrStage *E = InstrItins.end(SchedClass);
527           for (; S != E; ++S)
528             SU->Latency += S->Cycles;
529         }
530       }
531     }
532   }
533
534   // Pass 2: add the preds, succs, etc.
535   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
536     SUnit *SU = &SUnits[i];
537     SDNode   *N  = SU->Node;
538     NodeInfo *NI = getNI(N);
539     
540     if (N->isTargetOpcode() && TII->isTwoAddrInstr(N->getTargetOpcode()))
541       SU->isTwoAddress = true;
542
543     if (NI->isInGroup()) {
544       // Find all predecessors (of the group).
545       NodeGroupOpIterator NGOI(NI);
546       while (!NGOI.isEnd()) {
547         SDOperand Op  = NGOI.next();
548         SDNode   *OpN = Op.Val;
549         MVT::ValueType VT = OpN->getValueType(Op.ResNo);
550         NodeInfo *OpNI = getNI(OpN);
551         if (OpNI->Group != NI->Group && !isPassiveNode(OpN)) {
552           assert(VT != MVT::Flag);
553           SUnit *OpSU = SUnitMap[OpN];
554           if (VT == MVT::Other) {
555             if (SU->ChainPreds.insert(OpSU).second)
556               SU->NumChainPredsLeft++;
557             if (OpSU->ChainSuccs.insert(SU).second)
558               OpSU->NumChainSuccsLeft++;
559           } else {
560             if (SU->Preds.insert(OpSU).second)
561               SU->NumPredsLeft++;
562             if (OpSU->Succs.insert(SU).second)
563               OpSU->NumSuccsLeft++;
564           }
565         }
566       }
567     } else {
568       // Find node predecessors.
569       for (unsigned j = 0, e = N->getNumOperands(); j != e; j++) {
570         SDOperand Op  = N->getOperand(j);
571         SDNode   *OpN = Op.Val;
572         MVT::ValueType VT = OpN->getValueType(Op.ResNo);
573         if (!isPassiveNode(OpN)) {
574           assert(VT != MVT::Flag);
575           SUnit *OpSU = SUnitMap[OpN];
576           if (VT == MVT::Other) {
577             if (SU->ChainPreds.insert(OpSU).second)
578               SU->NumChainPredsLeft++;
579             if (OpSU->ChainSuccs.insert(SU).second)
580               OpSU->NumChainSuccsLeft++;
581           } else {
582             if (SU->Preds.insert(OpSU).second)
583               SU->NumPredsLeft++;
584             if (OpSU->Succs.insert(SU).second)
585               OpSU->NumSuccsLeft++;
586             if (j == 0 && SU->isTwoAddress) 
587               OpSU->isDefNUseOperand = true;
588           }
589         }
590       }
591     }
592     
593     DEBUG(SU->dumpAll(&DAG));
594   }
595 }
596
597 /// EmitSchedule - Emit the machine code in scheduled order.
598 void ScheduleDAGList::EmitSchedule() {
599   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
600     if (SUnit *SU = Sequence[i]) {
601       for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) {
602         SDNode *N = SU->FlaggedNodes[j];
603         EmitNode(getNI(N));
604       }
605       EmitNode(getNI(SU->Node));
606     } else {
607       // Null SUnit* is a noop.
608       EmitNoop();
609     }
610   }
611 }
612
613 /// dump - dump the schedule.
614 void ScheduleDAGList::dumpSchedule() const {
615   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
616     if (SUnit *SU = Sequence[i])
617       SU->dump(&DAG);
618     else
619       std::cerr << "**** NOOP ****\n";
620   }
621 }
622
623 /// Schedule - Schedule the DAG using list scheduling.
624 /// FIXME: Right now it only supports the burr (bottom up register reducing)
625 /// heuristic.
626 void ScheduleDAGList::Schedule() {
627   DEBUG(std::cerr << "********** List Scheduling **********\n");
628
629   // Build scheduling units.
630   BuildSchedUnits();
631   
632   PriorityQueue->initNodes(SUnits);
633   
634   // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate.
635   if (isBottomUp)
636     ListScheduleBottomUp();
637   else
638     ListScheduleTopDown();
639
640   PriorityQueue->releaseState();
641
642   DEBUG(std::cerr << "*** Final schedule ***\n");
643   DEBUG(dumpSchedule());
644   DEBUG(std::cerr << "\n");
645   
646   // Emit in scheduled order
647   EmitSchedule();
648 }
649
650 //===----------------------------------------------------------------------===//
651 //                RegReductionPriorityQueue Implementation
652 //===----------------------------------------------------------------------===//
653 //
654 // This is a SchedulingPriorityQueue that schedules using Sethi Ullman numbers
655 // to reduce register pressure.
656 // 
657 namespace {
658   class RegReductionPriorityQueue;
659   
660   /// Sorting functions for the Available queue.
661   struct ls_rr_sort : public std::binary_function<SUnit*, SUnit*, bool> {
662     RegReductionPriorityQueue *SPQ;
663     ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {}
664     ls_rr_sort(const ls_rr_sort &RHS) : SPQ(RHS.SPQ) {}
665     
666     bool operator()(const SUnit* left, const SUnit* right) const;
667   };
668 }  // end anonymous namespace
669
670 namespace {
671   class RegReductionPriorityQueue : public SchedulingPriorityQueue {
672     // SUnits - The SUnits for the current graph.
673     const std::vector<SUnit> *SUnits;
674     
675     // SethiUllmanNumbers - The SethiUllman number for each node.
676     std::vector<int> SethiUllmanNumbers;
677     
678     std::priority_queue<SUnit*, std::vector<SUnit*>, ls_rr_sort> Queue;
679   public:
680     RegReductionPriorityQueue() : Queue(ls_rr_sort(this)) {
681     }
682     
683     void initNodes(const std::vector<SUnit> &sunits) {
684       SUnits = &sunits;
685       // Calculate node priorities.
686       CalculatePriorities();
687     }
688     void releaseState() {
689       SUnits = 0;
690       SethiUllmanNumbers.clear();
691     }
692     
693     unsigned getSethiUllmanNumber(unsigned NodeNum) const {
694       assert(NodeNum < SethiUllmanNumbers.size());
695       return SethiUllmanNumbers[NodeNum];
696     }
697     
698     bool empty() const { return Queue.empty(); }
699     
700     void push(SUnit *U) {
701       Queue.push(U);
702     }
703     SUnit *pop() {
704       SUnit *V = Queue.top();
705       Queue.pop();
706       return V;
707     }
708   private:
709     void CalculatePriorities();
710     int CalcNodePriority(const SUnit *SU);
711   };
712 }
713
714 bool ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
715   unsigned LeftNum  = left->NodeNum;
716   unsigned RightNum = right->NodeNum;
717   
718   int LBonus = (int)left ->isDefNUseOperand;
719   int RBonus = (int)right->isDefNUseOperand;
720   
721   // Special tie breaker: if two nodes share a operand, the one that
722   // use it as a def&use operand is preferred.
723   if (left->isTwoAddress && !right->isTwoAddress) {
724     SDNode *DUNode = left->Node->getOperand(0).Val;
725     if (DUNode->isOperand(right->Node))
726       LBonus++;
727   }
728   if (!left->isTwoAddress && right->isTwoAddress) {
729     SDNode *DUNode = right->Node->getOperand(0).Val;
730     if (DUNode->isOperand(left->Node))
731       RBonus++;
732   }
733   
734   // Priority1 is just the number of live range genned.
735   int LPriority1 = left ->NumPredsLeft - LBonus;
736   int RPriority1 = right->NumPredsLeft - RBonus;
737   int LPriority2 = SPQ->getSethiUllmanNumber(LeftNum) + LBonus;
738   int RPriority2 = SPQ->getSethiUllmanNumber(RightNum) + RBonus;
739   
740   if (LPriority1 > RPriority1)
741     return true;
742   else if (LPriority1 == RPriority1)
743     if (LPriority2 < RPriority2)
744       return true;
745     else if (LPriority2 == RPriority2)
746       if (left->CycleBound > right->CycleBound) 
747         return true;
748   
749   return false;
750 }
751
752
753 /// CalcNodePriority - Priority is the Sethi Ullman number. 
754 /// Smaller number is the higher priority.
755 int RegReductionPriorityQueue::CalcNodePriority(const SUnit *SU) {
756   int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum];
757   if (SethiUllmanNumber != INT_MIN)
758     return SethiUllmanNumber;
759   
760   if (SU->Preds.size() == 0) {
761     SethiUllmanNumber = 1;
762   } else {
763     int Extra = 0;
764     for (std::set<SUnit*>::iterator I = SU->Preds.begin(),
765          E = SU->Preds.end(); I != E; ++I) {
766       SUnit *PredSU = *I;
767       int PredSethiUllman = CalcNodePriority(PredSU);
768       if (PredSethiUllman > SethiUllmanNumber) {
769         SethiUllmanNumber = PredSethiUllman;
770         Extra = 0;
771       } else if (PredSethiUllman == SethiUllmanNumber)
772         Extra++;
773     }
774     
775     if (SU->Node->getOpcode() != ISD::TokenFactor)
776       SethiUllmanNumber += Extra;
777     else
778       SethiUllmanNumber = (Extra == 1) ? 0 : Extra-1;
779   }
780   
781   return SethiUllmanNumber;
782 }
783
784 /// CalculatePriorities - Calculate priorities of all scheduling units.
785 void RegReductionPriorityQueue::CalculatePriorities() {
786   SethiUllmanNumbers.assign(SUnits->size(), INT_MIN);
787   
788   for (unsigned i = 0, e = SUnits->size(); i != e; ++i)
789     CalcNodePriority(&(*SUnits)[i]);
790 }
791
792 //===----------------------------------------------------------------------===//
793 //                    LatencyPriorityQueue Implementation
794 //===----------------------------------------------------------------------===//
795 //
796 // This is a SchedulingPriorityQueue that schedules using latency information to
797 // reduce the length of the critical path through the basic block.
798 // 
799 namespace {
800   class LatencyPriorityQueue;
801   
802   /// Sorting functions for the Available queue.
803   struct latency_sort : public std::binary_function<SUnit*, SUnit*, bool> {
804     LatencyPriorityQueue *PQ;
805     latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {}
806     latency_sort(const latency_sort &RHS) : PQ(RHS.PQ) {}
807     
808     bool operator()(const SUnit* left, const SUnit* right) const;
809   };
810 }  // end anonymous namespace
811
812 namespace {
813   class LatencyPriorityQueue : public SchedulingPriorityQueue {
814     // SUnits - The SUnits for the current graph.
815     const std::vector<SUnit> *SUnits;
816     
817     // Latencies - The latency (max of latency from this node to the bb exit)
818     // for each node.
819     std::vector<int> Latencies;
820     
821     std::priority_queue<SUnit*, std::vector<SUnit*>, latency_sort> Queue;
822 public:
823     LatencyPriorityQueue() : Queue(latency_sort(this)) {
824     }
825     
826     void initNodes(const std::vector<SUnit> &sunits) {
827       SUnits = &sunits;
828       // Calculate node priorities.
829       CalculatePriorities();
830     }
831     void releaseState() {
832       SUnits = 0;
833       Latencies.clear();
834     }
835     
836     unsigned getLatency(unsigned NodeNum) const {
837       assert(NodeNum < Latencies.size());
838       return Latencies[NodeNum];
839     }
840     
841     bool empty() const { return Queue.empty(); }
842     
843     void push(SUnit *U) {
844       Queue.push(U);
845     }
846     SUnit *pop() {
847       SUnit *V = Queue.top();
848       Queue.pop();
849       return V;
850     }
851 private:
852     void CalculatePriorities();
853     int CalcLatency(const SUnit &SU);
854   };
855 }
856
857 bool latency_sort::operator()(const SUnit *LHS, const SUnit *RHS) const {
858   unsigned LHSNum = LHS->NodeNum;
859   unsigned RHSNum = RHS->NodeNum;
860   
861   return PQ->getLatency(LHSNum) < PQ->getLatency(RHSNum);
862 }
863
864
865 /// CalcNodePriority - Calculate the maximal path from the node to the exit.
866 ///
867 int LatencyPriorityQueue::CalcLatency(const SUnit &SU) {
868   int &Latency = Latencies[SU.NodeNum];
869   if (Latency != -1)
870     return Latency;
871   
872   int MaxSuccLatency = 0;
873   for (std::set<SUnit*>::iterator I = SU.Succs.begin(),
874        E = SU.Succs.end(); I != E; ++I)
875     MaxSuccLatency = std::max(MaxSuccLatency, CalcLatency(**I));
876
877   for (std::set<SUnit*>::iterator I = SU.ChainSuccs.begin(),
878        E = SU.ChainSuccs.end(); I != E; ++I)
879     MaxSuccLatency = std::max(MaxSuccLatency, CalcLatency(**I));
880
881   return Latency = MaxSuccLatency + SU.Latency;
882 }
883
884 /// CalculatePriorities - Calculate priorities of all scheduling units.
885 void LatencyPriorityQueue::CalculatePriorities() {
886   Latencies.assign(SUnits->size(), -1);
887   
888   for (unsigned i = 0, e = SUnits->size(); i != e; ++i)
889     CalcLatency((*SUnits)[i]);
890 }
891
892
893 //===----------------------------------------------------------------------===//
894 //                         Public Constructor Functions
895 //===----------------------------------------------------------------------===//
896
897 llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG,
898                                                     MachineBasicBlock *BB) {
899   return new ScheduleDAGList(DAG, BB, DAG.getTarget(), true, 
900                              new RegReductionPriorityQueue(),
901                              new HazardRecognizer());
902 }
903
904 /// createTDListDAGScheduler - This creates a top-down list scheduler with the
905 /// specified hazard recognizer.
906 ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAG &DAG,
907                                             MachineBasicBlock *BB,
908                                             HazardRecognizer *HR) {
909   return new ScheduleDAGList(DAG, BB, DAG.getTarget(), false,
910                              new LatencyPriorityQueue(),
911                              HR);
912 }