Remove some code that doesn't make sense
[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 a simple two pass scheduler.  The first pass attempts to push
11 // backward any lengthy instructions and critical paths.  The second pass packs
12 // instructions into semi-optimal time slots.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #define DEBUG_TYPE "sched"
17 #include "llvm/CodeGen/ScheduleDAG.h"
18 #include "llvm/CodeGen/SelectionDAG.h"
19 #include "llvm/Target/TargetMachine.h"
20 #include "llvm/Target/TargetInstrInfo.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/ADT/Statistic.h"
23 #include <climits>
24 #include <iostream>
25 #include <queue>
26 #include <set>
27 #include <vector>
28 using namespace llvm;
29
30 namespace {
31   Statistic<> NumNoops ("scheduler", "Number of noops inserted");
32   Statistic<> NumStalls("scheduler", "Number of pipeline stalls");
33
34 /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or a
35 /// group of nodes flagged together.
36 struct SUnit {
37   SDNode *Node;                       // Representative node.
38   std::vector<SDNode*> FlaggedNodes;  // All nodes flagged to Node.
39   std::set<SUnit*> Preds;             // All real predecessors.
40   std::set<SUnit*> ChainPreds;        // All chain predecessors.
41   std::set<SUnit*> Succs;             // All real successors.
42   std::set<SUnit*> ChainSuccs;        // All chain successors.
43   int NumPredsLeft;                   // # of preds not scheduled.
44   int NumSuccsLeft;                   // # of succs not scheduled.
45   int NumChainPredsLeft;              // # of chain preds not scheduled.
46   int NumChainSuccsLeft;              // # of chain succs not scheduled.
47   int SethiUllman;                    // Sethi Ullman number.
48   bool isTwoAddress;                  // Is a two-address instruction.
49   bool isDefNUseOperand;              // Is a def&use operand.
50   unsigned Latency;                   // Node latency.
51   unsigned CycleBound;                // Upper/lower cycle to be scheduled at.
52   unsigned Slot;                      // Cycle node is scheduled at.
53   SUnit *Next;
54
55   SUnit(SDNode *node)
56     : Node(node), NumPredsLeft(0), NumSuccsLeft(0),
57       NumChainPredsLeft(0), NumChainSuccsLeft(0),
58       SethiUllman(INT_MIN),
59       isTwoAddress(false), isDefNUseOperand(false),
60       Latency(0), CycleBound(0), Slot(0), Next(NULL) {}
61
62   void dump(const SelectionDAG *G, bool All=true) const;
63 };
64
65 void SUnit::dump(const SelectionDAG *G, bool All) const {
66   std::cerr << "SU: ";
67   Node->dump(G);
68   std::cerr << "\n";
69   if (FlaggedNodes.size() != 0) {
70     for (unsigned i = 0, e = FlaggedNodes.size(); i != e; i++) {
71       std::cerr << "    ";
72       FlaggedNodes[i]->dump(G);
73       std::cerr << "\n";
74     }
75   }
76
77   if (All) {
78     std::cerr << "  # preds left       : " << NumPredsLeft << "\n";
79     std::cerr << "  # succs left       : " << NumSuccsLeft << "\n";
80     std::cerr << "  # chain preds left : " << NumChainPredsLeft << "\n";
81     std::cerr << "  # chain succs left : " << NumChainSuccsLeft << "\n";
82     std::cerr << "  Latency            : " << Latency << "\n";
83     std::cerr << "  SethiUllman        : " << SethiUllman << "\n";
84
85     if (Preds.size() != 0) {
86       std::cerr << "  Predecessors:\n";
87       for (std::set<SUnit*>::const_iterator I = Preds.begin(),
88              E = Preds.end(); I != E; ++I) {
89         std::cerr << "    ";
90         (*I)->dump(G, false);
91       }
92     }
93     if (ChainPreds.size() != 0) {
94       std::cerr << "  Chained Preds:\n";
95       for (std::set<SUnit*>::const_iterator I = ChainPreds.begin(),
96              E = ChainPreds.end(); I != E; ++I) {
97         std::cerr << "    ";
98         (*I)->dump(G, false);
99       }
100     }
101     if (Succs.size() != 0) {
102       std::cerr << "  Successors:\n";
103       for (std::set<SUnit*>::const_iterator I = Succs.begin(),
104              E = Succs.end(); I != E; ++I) {
105         std::cerr << "    ";
106         (*I)->dump(G, false);
107       }
108     }
109     if (ChainSuccs.size() != 0) {
110       std::cerr << "  Chained succs:\n";
111       for (std::set<SUnit*>::const_iterator I = ChainSuccs.begin(),
112              E = ChainSuccs.end(); I != E; ++I) {
113         std::cerr << "    ";
114         (*I)->dump(G, false);
115       }
116     }
117   }
118 }
119
120 /// Sorting functions for the Available queue.
121 struct ls_rr_sort : public std::binary_function<SUnit*, SUnit*, bool> {
122   bool operator()(const SUnit* left, const SUnit* right) const {
123     int LBonus = (int)left ->isDefNUseOperand;
124     int RBonus = (int)right->isDefNUseOperand;
125
126     // Special tie breaker: if two nodes share a operand, the one that
127     // use it as a def&use operand is preferred.
128     if (left->isTwoAddress && !right->isTwoAddress) {
129       SDNode *DUNode = left->Node->getOperand(0).Val;
130       if (DUNode->isOperand(right->Node))
131         LBonus++;
132     }
133     if (!left->isTwoAddress && right->isTwoAddress) {
134       SDNode *DUNode = right->Node->getOperand(0).Val;
135       if (DUNode->isOperand(left->Node))
136         RBonus++;
137     }
138
139     // Priority1 is just the number of live range genned.
140     int LPriority1 = left ->NumPredsLeft - LBonus;
141     int RPriority1 = right->NumPredsLeft - RBonus;
142     int LPriority2 = left ->SethiUllman + LBonus;
143     int RPriority2 = right->SethiUllman + RBonus;
144
145     if (LPriority1 > RPriority1)
146       return true;
147     else if (LPriority1 == RPriority1)
148       if (LPriority2 < RPriority2)
149         return true;
150       else if (LPriority2 == RPriority2)
151         if (left->CycleBound > right->CycleBound) 
152           return true;
153
154     return false;
155   }
156 };
157
158
159 /// ScheduleDAGList - List scheduler.
160 class ScheduleDAGList : public ScheduleDAG {
161 private:
162   // SDNode to SUnit mapping (many to one).
163   std::map<SDNode*, SUnit*> SUnitMap;
164   // The schedule.  Null SUnit*'s represent noop instructions.
165   std::vector<SUnit*> Sequence;
166   // Current scheduling cycle.
167   unsigned CurrCycle;
168   // First and last SUnit created.
169   SUnit *HeadSUnit, *TailSUnit;
170
171   /// isBottomUp - This is true if the scheduling problem is bottom-up, false if
172   /// it is top-down.
173   bool isBottomUp;
174   
175   /// HazardRec - The hazard recognizer to use.
176   HazardRecognizer &HazardRec;
177   
178   typedef std::priority_queue<SUnit*, std::vector<SUnit*>, ls_rr_sort>
179     AvailableQueueTy;
180
181 public:
182   ScheduleDAGList(SelectionDAG &dag, MachineBasicBlock *bb,
183                   const TargetMachine &tm, bool isbottomup,
184                   HazardRecognizer &HR)
185     : ScheduleDAG(listSchedulingBURR, dag, bb, tm),
186       CurrCycle(0), HeadSUnit(NULL), TailSUnit(NULL), isBottomUp(isbottomup),
187       HazardRec(HR) {
188     }
189
190   ~ScheduleDAGList() {
191     SUnit *SU = HeadSUnit;
192     while (SU) {
193       SUnit *NextSU = SU->Next;
194       delete SU;
195       SU = NextSU;
196     }
197   }
198
199   void Schedule();
200
201   void dump() const;
202
203 private:
204   SUnit *NewSUnit(SDNode *N);
205   void ReleasePred(AvailableQueueTy &Avail,SUnit *PredSU, bool isChain = false);
206   void ReleaseSucc(AvailableQueueTy &Avail,SUnit *SuccSU, bool isChain = false);
207   void ScheduleNodeBottomUp(AvailableQueueTy &Avail, SUnit *SU);
208   void ScheduleNodeTopDown(AvailableQueueTy &Avail, SUnit *SU);
209   int  CalcNodePriority(SUnit *SU);
210   void CalculatePriorities();
211   void ListScheduleTopDown();
212   void ListScheduleBottomUp();
213   void BuildSchedUnits();
214   void EmitSchedule();
215 };
216 }  // end namespace
217
218 HazardRecognizer::~HazardRecognizer() {}
219
220
221 /// NewSUnit - Creates a new SUnit and return a ptr to it.
222 SUnit *ScheduleDAGList::NewSUnit(SDNode *N) {
223   SUnit *CurrSUnit = new SUnit(N);
224
225   if (HeadSUnit == NULL)
226     HeadSUnit = CurrSUnit;
227   if (TailSUnit != NULL)
228     TailSUnit->Next = CurrSUnit;
229   TailSUnit = CurrSUnit;
230
231   return CurrSUnit;
232 }
233
234 /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to
235 /// the Available queue is the count reaches zero. Also update its cycle bound.
236 void ScheduleDAGList::ReleasePred(AvailableQueueTy &Available, 
237                                   SUnit *PredSU, bool isChain) {
238   // FIXME: the distance between two nodes is not always == the predecessor's
239   // latency. For example, the reader can very well read the register written
240   // by the predecessor later than the issue cycle. It also depends on the
241   // interrupt model (drain vs. freeze).
242   PredSU->CycleBound = std::max(PredSU->CycleBound, CurrCycle + PredSU->Latency);
243
244   if (!isChain)
245     PredSU->NumSuccsLeft--;
246   else
247     PredSU->NumChainSuccsLeft--;
248   
249 #ifndef NDEBUG
250   if (PredSU->NumSuccsLeft < 0 || PredSU->NumChainSuccsLeft < 0) {
251     std::cerr << "*** List scheduling failed! ***\n";
252     PredSU->dump(&DAG);
253     std::cerr << " has been released too many times!\n";
254     assert(0);
255   }
256 #endif
257   
258   if ((PredSU->NumSuccsLeft + PredSU->NumChainSuccsLeft) == 0) {
259     // EntryToken has to go last!  Special case it here.
260     if (PredSU->Node->getOpcode() != ISD::EntryToken)
261       Available.push(PredSU);
262   }
263 }
264
265 /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to
266 /// the Available queue is the count reaches zero. Also update its cycle bound.
267 void ScheduleDAGList::ReleaseSucc(AvailableQueueTy &Available, 
268                                   SUnit *SuccSU, bool isChain) {
269   // FIXME: the distance between two nodes is not always == the predecessor's
270   // latency. For example, the reader can very well read the register written
271   // by the predecessor later than the issue cycle. It also depends on the
272   // interrupt model (drain vs. freeze).
273   SuccSU->CycleBound = std::max(SuccSU->CycleBound, CurrCycle + SuccSU->Latency);
274   
275   if (!isChain)
276     SuccSU->NumPredsLeft--;
277   else
278     SuccSU->NumChainPredsLeft--;
279   
280 #ifndef NDEBUG
281   if (SuccSU->NumPredsLeft < 0 || SuccSU->NumChainPredsLeft < 0) {
282     std::cerr << "*** List scheduling failed! ***\n";
283     SuccSU->dump(&DAG);
284     std::cerr << " has been released too many times!\n";
285     abort();
286   }
287 #endif
288   
289   if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0)
290     Available.push(SuccSU);
291 }
292
293 /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending
294 /// count of its predecessors. If a predecessor pending count is zero, add it to
295 /// the Available queue.
296 void ScheduleDAGList::ScheduleNodeBottomUp(AvailableQueueTy &Available,
297                                            SUnit *SU) {
298   DEBUG(std::cerr << "*** Scheduling: ");
299   DEBUG(SU->dump(&DAG, false));
300
301   Sequence.push_back(SU);
302   SU->Slot = CurrCycle;
303
304   // Bottom up: release predecessors
305   for (std::set<SUnit*>::iterator I1 = SU->Preds.begin(),
306          E1 = SU->Preds.end(); I1 != E1; ++I1) {
307     ReleasePred(Available, *I1);
308     SU->NumPredsLeft--;
309   }
310   for (std::set<SUnit*>::iterator I2 = SU->ChainPreds.begin(),
311          E2 = SU->ChainPreds.end(); I2 != E2; ++I2)
312     ReleasePred(Available, *I2, true);
313
314   CurrCycle++;
315 }
316
317 /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending
318 /// count of its successors. If a successor pending count is zero, add it to
319 /// the Available queue.
320 void ScheduleDAGList::ScheduleNodeTopDown(AvailableQueueTy &Available,
321                                           SUnit *SU) {
322   DEBUG(std::cerr << "*** Scheduling: ");
323   DEBUG(SU->dump(&DAG, false));
324   
325   Sequence.push_back(SU);
326   SU->Slot = CurrCycle;
327   
328   // Bottom up: release successors.
329   for (std::set<SUnit*>::iterator I1 = SU->Succs.begin(),
330        E1 = SU->Succs.end(); I1 != E1; ++I1) {
331     ReleaseSucc(Available, *I1);
332     SU->NumSuccsLeft--;
333   }
334   for (std::set<SUnit*>::iterator I2 = SU->ChainSuccs.begin(),
335        E2 = SU->ChainSuccs.end(); I2 != E2; ++I2)
336     ReleaseSucc(Available, *I2, true);
337   
338   CurrCycle++;
339 }
340
341 /// isReady - True if node's lower cycle bound is less or equal to the current
342 /// scheduling cycle. Always true if all nodes have uniform latency 1.
343 static inline bool isReady(SUnit *SU, unsigned CurrCycle) {
344   return SU->CycleBound <= CurrCycle;
345 }
346
347 /// ListScheduleBottomUp - The main loop of list scheduling for bottom-up
348 /// schedulers.
349 void ScheduleDAGList::ListScheduleBottomUp() {
350   // Available queue.
351   AvailableQueueTy Available;
352
353   // Add root to Available queue.
354   Available.push(SUnitMap[DAG.getRoot().Val]);
355
356   // While Available queue is not empty, grab the node with the highest
357   // priority. If it is not ready put it back. Schedule the node.
358   std::vector<SUnit*> NotReady;
359   while (!Available.empty()) {
360     SUnit *CurrNode = Available.top();
361     Available.pop();
362
363     while (!isReady(CurrNode, CurrCycle)) {
364       NotReady.push_back(CurrNode);
365       CurrNode = Available.top();
366       Available.pop();
367     }
368     
369     // Add the nodes that aren't ready back onto the available list.
370     while (!NotReady.empty()) {
371       Available.push(NotReady.back());
372       NotReady.pop_back();
373     }
374
375     ScheduleNodeBottomUp(Available, CurrNode);
376   }
377
378   // Add entry node last
379   if (DAG.getEntryNode().Val != DAG.getRoot().Val) {
380     SUnit *Entry = SUnitMap[DAG.getEntryNode().Val];
381     Entry->Slot = CurrCycle;
382     Sequence.push_back(Entry);
383   }
384
385   // Reverse the order if it is bottom up.
386   std::reverse(Sequence.begin(), Sequence.end());
387   
388   
389 #ifndef NDEBUG
390   // Verify that all SUnits were scheduled.
391   bool AnyNotSched = false;
392   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
393     if (SU->NumSuccsLeft != 0 || SU->NumChainSuccsLeft != 0) {
394       if (!AnyNotSched)
395         std::cerr << "*** List scheduling failed! ***\n";
396       SU->dump(&DAG);
397       std::cerr << "has not been scheduled!\n";
398       AnyNotSched = true;
399     }
400   }
401   assert(!AnyNotSched);
402 #endif
403 }
404
405 /// ListScheduleTopDown - The main loop of list scheduling for top-down
406 /// schedulers.
407 void ScheduleDAGList::ListScheduleTopDown() {
408   // Available queue.
409   AvailableQueueTy Available;
410
411   HazardRec.StartBasicBlock();
412   
413   // Emit the entry node first.
414   SUnit *Entry = SUnitMap[DAG.getEntryNode().Val];
415   ScheduleNodeTopDown(Available, Entry);
416   HazardRec.EmitInstruction(Entry->Node);
417                       
418   // All leaves to Available queue.
419   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
420     // It is available if it has no predecessors.
421     if ((SU->Preds.size() + SU->ChainPreds.size()) == 0 && SU != Entry)
422       Available.push(SU);
423   }
424   
425   // While Available queue is not empty, grab the node with the highest
426   // priority. If it is not ready put it back.  Schedule the node.
427   std::vector<SUnit*> NotReady;
428   while (!Available.empty()) {
429     SUnit *FoundNode = 0;
430
431     bool HasNoopHazards = false;
432     do {
433       SUnit *CurrNode = Available.top();
434       Available.pop();
435       HazardRecognizer::HazardType HT =
436         HazardRec.getHazardType(CurrNode->Node);
437       if (HT == HazardRecognizer::NoHazard) {
438         FoundNode = CurrNode;
439         break;
440       }
441       
442       // Remember if this is a noop hazard.
443       HasNoopHazards |= HT == HazardRecognizer::NoopHazard;
444       
445       NotReady.push_back(CurrNode);
446     } while (!Available.empty());
447     
448     // Add the nodes that aren't ready back onto the available list.
449     while (!NotReady.empty()) {
450       Available.push(NotReady.back());
451       NotReady.pop_back();
452     }
453
454     // If we found a node to schedule, do it now.
455     if (FoundNode) {
456       ScheduleNodeTopDown(Available, FoundNode);
457       HazardRec.EmitInstruction(FoundNode->Node);
458     } else if (!HasNoopHazards) {
459       // Otherwise, we have a pipeline stall, but no other problem, just advance
460       // the current cycle and try again.
461       DEBUG(std::cerr << "*** Advancing cycle, no work to do");
462       HazardRec.AdvanceCycle();
463       ++NumStalls;
464     } else {
465       // Otherwise, we have no instructions to issue and we have instructions
466       // that will fault if we don't do this right.  This is the case for
467       // processors without pipeline interlocks and other cases.
468       DEBUG(std::cerr << "*** Emitting noop");
469       HazardRec.EmitNoop();
470       Sequence.push_back(0);   // NULL SUnit* -> noop
471       ++NumNoops;
472     }
473   }
474
475 #ifndef NDEBUG
476   // Verify that all SUnits were scheduled.
477   bool AnyNotSched = false;
478   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
479     if (SU->NumPredsLeft != 0 || SU->NumChainPredsLeft != 0) {
480       if (!AnyNotSched)
481         std::cerr << "*** List scheduling failed! ***\n";
482       SU->dump(&DAG);
483       std::cerr << "has not been scheduled!\n";
484       AnyNotSched = true;
485     }
486   }
487   assert(!AnyNotSched);
488 #endif
489 }
490
491
492 /// CalcNodePriority - Priority is the Sethi Ullman number. 
493 /// Smaller number is the higher priority.
494 int ScheduleDAGList::CalcNodePriority(SUnit *SU) {
495   if (SU->SethiUllman != INT_MIN)
496     return SU->SethiUllman;
497
498   if (SU->Preds.size() == 0) {
499     SU->SethiUllman = 1;
500   } else {
501     int Extra = 0;
502     for (std::set<SUnit*>::iterator I = SU->Preds.begin(),
503            E = SU->Preds.end(); I != E; ++I) {
504       SUnit *PredSU = *I;
505       int PredSethiUllman = CalcNodePriority(PredSU);
506       if (PredSethiUllman > SU->SethiUllman) {
507         SU->SethiUllman = PredSethiUllman;
508         Extra = 0;
509       } else if (PredSethiUllman == SU->SethiUllman)
510         Extra++;
511     }
512
513     if (SU->Node->getOpcode() != ISD::TokenFactor)
514       SU->SethiUllman += Extra;
515     else
516       SU->SethiUllman = (Extra == 1) ? 0 : Extra-1;
517   }
518
519   return SU->SethiUllman;
520 }
521
522 /// CalculatePriorities - Calculate priorities of all scheduling units.
523 void ScheduleDAGList::CalculatePriorities() {
524   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
525     // FIXME: assumes uniform latency for now.
526     SU->Latency = 1;
527     (void)CalcNodePriority(SU);
528     DEBUG(SU->dump(&DAG));
529     DEBUG(std::cerr << "\n");
530   }
531 }
532
533 void ScheduleDAGList::BuildSchedUnits() {
534   // Pass 1: create the SUnit's.
535   for (unsigned i = 0, NC = NodeCount; i < NC; i++) {
536     NodeInfo *NI = &Info[i];
537     SDNode *N = NI->Node;
538     if (isPassiveNode(N))
539       continue;
540
541     SUnit *SU;
542     if (NI->isInGroup()) {
543       if (NI != NI->Group->getBottom())  // Bottom up, so only look at bottom
544         continue;                        // node of the NodeGroup
545
546       SU = NewSUnit(N);
547       // Find the flagged nodes.
548       SDOperand  FlagOp = N->getOperand(N->getNumOperands() - 1);
549       SDNode    *Flag   = FlagOp.Val;
550       unsigned   ResNo  = FlagOp.ResNo;
551       while (Flag->getValueType(ResNo) == MVT::Flag) {
552         NodeInfo *FNI = getNI(Flag);
553         assert(FNI->Group == NI->Group);
554         SU->FlaggedNodes.insert(SU->FlaggedNodes.begin(), Flag);
555         SUnitMap[Flag] = SU;
556
557         FlagOp = Flag->getOperand(Flag->getNumOperands() - 1);
558         Flag   = FlagOp.Val;
559         ResNo  = FlagOp.ResNo;
560       }
561     } else {
562       SU = NewSUnit(N);
563     }
564     SUnitMap[N] = SU;
565   }
566
567   // Pass 2: add the preds, succs, etc.
568   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
569     SDNode   *N  = SU->Node;
570     NodeInfo *NI = getNI(N);
571     
572     if (N->isTargetOpcode() && TII->isTwoAddrInstr(N->getTargetOpcode()))
573       SU->isTwoAddress = true;
574
575     if (NI->isInGroup()) {
576       // Find all predecessors (of the group).
577       NodeGroupOpIterator NGOI(NI);
578       while (!NGOI.isEnd()) {
579         SDOperand Op  = NGOI.next();
580         SDNode   *OpN = Op.Val;
581         MVT::ValueType VT = OpN->getValueType(Op.ResNo);
582         NodeInfo *OpNI = getNI(OpN);
583         if (OpNI->Group != NI->Group && !isPassiveNode(OpN)) {
584           assert(VT != MVT::Flag);
585           SUnit *OpSU = SUnitMap[OpN];
586           if (VT == MVT::Other) {
587             if (SU->ChainPreds.insert(OpSU).second)
588               SU->NumChainPredsLeft++;
589             if (OpSU->ChainSuccs.insert(SU).second)
590               OpSU->NumChainSuccsLeft++;
591           } else {
592             if (SU->Preds.insert(OpSU).second)
593               SU->NumPredsLeft++;
594             if (OpSU->Succs.insert(SU).second)
595               OpSU->NumSuccsLeft++;
596           }
597         }
598       }
599     } else {
600       // Find node predecessors.
601       for (unsigned j = 0, e = N->getNumOperands(); j != e; j++) {
602         SDOperand Op  = N->getOperand(j);
603         SDNode   *OpN = Op.Val;
604         MVT::ValueType VT = OpN->getValueType(Op.ResNo);
605         if (!isPassiveNode(OpN)) {
606           assert(VT != MVT::Flag);
607           SUnit *OpSU = SUnitMap[OpN];
608           if (VT == MVT::Other) {
609             if (SU->ChainPreds.insert(OpSU).second)
610               SU->NumChainPredsLeft++;
611             if (OpSU->ChainSuccs.insert(SU).second)
612               OpSU->NumChainSuccsLeft++;
613           } else {
614             if (SU->Preds.insert(OpSU).second)
615               SU->NumPredsLeft++;
616             if (OpSU->Succs.insert(SU).second)
617               OpSU->NumSuccsLeft++;
618             if (j == 0 && SU->isTwoAddress) 
619               OpSU->isDefNUseOperand = true;
620           }
621         }
622       }
623     }
624   }
625 }
626
627 /// EmitSchedule - Emit the machine code in scheduled order.
628 void ScheduleDAGList::EmitSchedule() {
629   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
630     if (SUnit *SU = Sequence[i]) {
631       for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) {
632         SDNode *N = SU->FlaggedNodes[j];
633         EmitNode(getNI(N));
634       }
635       EmitNode(getNI(SU->Node));
636     } else {
637       // Null SUnit* is a noop.
638       EmitNoop();
639     }
640   }
641 }
642
643 /// dump - dump the schedule.
644 void ScheduleDAGList::dump() const {
645   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
646     if (SUnit *SU = Sequence[i])
647       SU->dump(&DAG, false);
648     else
649       std::cerr << "**** NOOP ****\n";
650   }
651 }
652
653 /// Schedule - Schedule the DAG using list scheduling.
654 /// FIXME: Right now it only supports the burr (bottom up register reducing)
655 /// heuristic.
656 void ScheduleDAGList::Schedule() {
657   DEBUG(std::cerr << "********** List Scheduling **********\n");
658
659   // Build scheduling units.
660   BuildSchedUnits();
661
662   // Calculate node priorities.
663   CalculatePriorities();
664
665   // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate.
666   if (isBottomUp)
667     ListScheduleBottomUp();
668   else
669     ListScheduleTopDown();
670   
671   DEBUG(std::cerr << "*** Final schedule ***\n");
672   DEBUG(dump());
673   DEBUG(std::cerr << "\n");
674   
675   // Emit in scheduled order
676   EmitSchedule();
677 }
678
679 llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG,
680                                                     MachineBasicBlock *BB) {
681   HazardRecognizer HR;
682   return new ScheduleDAGList(DAG, BB, DAG.getTarget(), true, HR);
683 }
684
685 /// createTDListDAGScheduler - This creates a top-down list scheduler with the
686 /// specified hazard recognizer.
687 ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAG &DAG,
688                                             MachineBasicBlock *BB,
689                                             HazardRecognizer &HR) {
690   return new ScheduleDAGList(DAG, BB, DAG.getTarget(), false, HR);
691 }