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