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