e089d0bc0f66867febc47469240affa6d36360fb
[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     delete HazardRec;
203   }
204
205   void Schedule();
206
207   void dump() const;
208
209 private:
210   SUnit *NewSUnit(SDNode *N);
211   void ReleasePred(AvailableQueueTy &Avail,SUnit *PredSU, bool isChain = false);
212   void ReleaseSucc(AvailableQueueTy &Avail,SUnit *SuccSU, bool isChain = false);
213   void ScheduleNodeBottomUp(AvailableQueueTy &Avail, SUnit *SU);
214   void ScheduleNodeTopDown(AvailableQueueTy &Avail, SUnit *SU);
215   int  CalcNodePriority(SUnit *SU);
216   void CalculatePriorities();
217   void ListScheduleTopDown();
218   void ListScheduleBottomUp();
219   void BuildSchedUnits();
220   void EmitSchedule();
221 };
222 }  // end namespace
223
224 HazardRecognizer::~HazardRecognizer() {}
225
226
227 /// NewSUnit - Creates a new SUnit and return a ptr to it.
228 SUnit *ScheduleDAGList::NewSUnit(SDNode *N) {
229   SUnit *CurrSUnit = new SUnit(N);
230
231   if (HeadSUnit == NULL)
232     HeadSUnit = CurrSUnit;
233   if (TailSUnit != NULL)
234     TailSUnit->Next = CurrSUnit;
235   TailSUnit = CurrSUnit;
236
237   return CurrSUnit;
238 }
239
240 /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to
241 /// the Available queue is the count reaches zero. Also update its cycle bound.
242 void ScheduleDAGList::ReleasePred(AvailableQueueTy &Available, 
243                                   SUnit *PredSU, bool isChain) {
244   // FIXME: the distance between two nodes is not always == the predecessor's
245   // latency. For example, the reader can very well read the register written
246   // by the predecessor later than the issue cycle. It also depends on the
247   // interrupt model (drain vs. freeze).
248   PredSU->CycleBound = std::max(PredSU->CycleBound, CurrCycle + PredSU->Latency);
249
250   if (!isChain)
251     PredSU->NumSuccsLeft--;
252   else
253     PredSU->NumChainSuccsLeft--;
254   
255 #ifndef NDEBUG
256   if (PredSU->NumSuccsLeft < 0 || PredSU->NumChainSuccsLeft < 0) {
257     std::cerr << "*** List scheduling failed! ***\n";
258     PredSU->dump(&DAG);
259     std::cerr << " has been released too many times!\n";
260     assert(0);
261   }
262 #endif
263   
264   if ((PredSU->NumSuccsLeft + PredSU->NumChainSuccsLeft) == 0) {
265     // EntryToken has to go last!  Special case it here.
266     if (PredSU->Node->getOpcode() != ISD::EntryToken)
267       Available.push(PredSU);
268   }
269 }
270
271 /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to
272 /// the Available queue is the count reaches zero. Also update its cycle bound.
273 void ScheduleDAGList::ReleaseSucc(AvailableQueueTy &Available, 
274                                   SUnit *SuccSU, bool isChain) {
275   // FIXME: the distance between two nodes is not always == the predecessor's
276   // latency. For example, the reader can very well read the register written
277   // by the predecessor later than the issue cycle. It also depends on the
278   // interrupt model (drain vs. freeze).
279   SuccSU->CycleBound = std::max(SuccSU->CycleBound, CurrCycle + SuccSU->Latency);
280   
281   if (!isChain)
282     SuccSU->NumPredsLeft--;
283   else
284     SuccSU->NumChainPredsLeft--;
285   
286 #ifndef NDEBUG
287   if (SuccSU->NumPredsLeft < 0 || SuccSU->NumChainPredsLeft < 0) {
288     std::cerr << "*** List scheduling failed! ***\n";
289     SuccSU->dump(&DAG);
290     std::cerr << " has been released too many times!\n";
291     abort();
292   }
293 #endif
294   
295   if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0)
296     Available.push(SuccSU);
297 }
298
299 /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending
300 /// count of its predecessors. If a predecessor pending count is zero, add it to
301 /// the Available queue.
302 void ScheduleDAGList::ScheduleNodeBottomUp(AvailableQueueTy &Available,
303                                            SUnit *SU) {
304   DEBUG(std::cerr << "*** Scheduling: ");
305   DEBUG(SU->dump(&DAG, false));
306
307   Sequence.push_back(SU);
308   SU->Slot = CurrCycle;
309
310   // Bottom up: release predecessors
311   for (std::set<SUnit*>::iterator I1 = SU->Preds.begin(),
312          E1 = SU->Preds.end(); I1 != E1; ++I1) {
313     ReleasePred(Available, *I1);
314     SU->NumPredsLeft--;
315   }
316   for (std::set<SUnit*>::iterator I2 = SU->ChainPreds.begin(),
317          E2 = SU->ChainPreds.end(); I2 != E2; ++I2)
318     ReleasePred(Available, *I2, true);
319
320   CurrCycle++;
321 }
322
323 /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending
324 /// count of its successors. If a successor pending count is zero, add it to
325 /// the Available queue.
326 void ScheduleDAGList::ScheduleNodeTopDown(AvailableQueueTy &Available,
327                                           SUnit *SU) {
328   DEBUG(std::cerr << "*** Scheduling: ");
329   DEBUG(SU->dump(&DAG, false));
330   
331   Sequence.push_back(SU);
332   SU->Slot = CurrCycle;
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     Entry->Slot = CurrCycle;
388     Sequence.push_back(Entry);
389   }
390
391   // Reverse the order if it is bottom up.
392   std::reverse(Sequence.begin(), Sequence.end());
393   
394   
395 #ifndef NDEBUG
396   // Verify that all SUnits were scheduled.
397   bool AnyNotSched = false;
398   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
399     if (SU->NumSuccsLeft != 0 || SU->NumChainSuccsLeft != 0) {
400       if (!AnyNotSched)
401         std::cerr << "*** List scheduling failed! ***\n";
402       SU->dump(&DAG);
403       std::cerr << "has not been scheduled!\n";
404       AnyNotSched = true;
405     }
406   }
407   assert(!AnyNotSched);
408 #endif
409 }
410
411 /// ListScheduleTopDown - The main loop of list scheduling for top-down
412 /// schedulers.
413 void ScheduleDAGList::ListScheduleTopDown() {
414   // Available queue.
415   AvailableQueueTy Available;
416
417   // Emit the entry node first.
418   SUnit *Entry = SUnitMap[DAG.getEntryNode().Val];
419   ScheduleNodeTopDown(Available, Entry);
420   HazardRec->EmitInstruction(Entry->Node);
421                       
422   // All leaves to Available queue.
423   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
424     // It is available if it has no predecessors.
425     if ((SU->Preds.size() + SU->ChainPreds.size()) == 0 && SU != Entry)
426       Available.push(SU);
427   }
428   
429   // While Available queue is not empty, grab the node with the highest
430   // priority. If it is not ready put it back.  Schedule the node.
431   std::vector<SUnit*> NotReady;
432   while (!Available.empty()) {
433     SUnit *FoundNode = 0;
434
435     bool HasNoopHazards = false;
436     do {
437       SUnit *CurNode = Available.top();
438       Available.pop();
439       
440       // Get the node represented by this SUnit.
441       SDNode *N = CurNode->Node;
442       // If this is a pseudo op, like copyfromreg, look to see if there is a
443       // real target node flagged to it.  If so, use the target node.
444       for (unsigned i = 0, e = CurNode->FlaggedNodes.size(); 
445            N->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i)
446         N = CurNode->FlaggedNodes[i];
447       
448       HazardRecognizer::HazardType HT = HazardRec->getHazardType(N);
449       if (HT == HazardRecognizer::NoHazard) {
450         FoundNode = CurNode;
451         break;
452       }
453       
454       // Remember if this is a noop hazard.
455       HasNoopHazards |= HT == HazardRecognizer::NoopHazard;
456       
457       NotReady.push_back(CurNode);
458     } while (!Available.empty());
459     
460     // Add the nodes that aren't ready back onto the available list.
461     while (!NotReady.empty()) {
462       Available.push(NotReady.back());
463       NotReady.pop_back();
464     }
465
466     // If we found a node to schedule, do it now.
467     if (FoundNode) {
468       ScheduleNodeTopDown(Available, FoundNode);
469       HazardRec->EmitInstruction(FoundNode->Node);
470     } else if (!HasNoopHazards) {
471       // Otherwise, we have a pipeline stall, but no other problem, just advance
472       // the current cycle and try again.
473       DEBUG(std::cerr << "*** Advancing cycle, no work to do\n");
474       HazardRec->AdvanceCycle();
475       ++NumStalls;
476     } else {
477       // Otherwise, we have no instructions to issue and we have instructions
478       // that will fault if we don't do this right.  This is the case for
479       // processors without pipeline interlocks and other cases.
480       DEBUG(std::cerr << "*** Emitting noop\n");
481       HazardRec->EmitNoop();
482       Sequence.push_back(0);   // NULL SUnit* -> noop
483       ++NumNoops;
484     }
485   }
486
487 #ifndef NDEBUG
488   // Verify that all SUnits were scheduled.
489   bool AnyNotSched = false;
490   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
491     if (SU->NumPredsLeft != 0 || SU->NumChainPredsLeft != 0) {
492       if (!AnyNotSched)
493         std::cerr << "*** List scheduling failed! ***\n";
494       SU->dump(&DAG);
495       std::cerr << "has not been scheduled!\n";
496       AnyNotSched = true;
497     }
498   }
499   assert(!AnyNotSched);
500 #endif
501 }
502
503
504 /// CalcNodePriority - Priority is the Sethi Ullman number. 
505 /// Smaller number is the higher priority.
506 int ScheduleDAGList::CalcNodePriority(SUnit *SU) {
507   if (SU->SethiUllman != INT_MIN)
508     return SU->SethiUllman;
509
510   if (SU->Preds.size() == 0) {
511     SU->SethiUllman = 1;
512   } else {
513     int Extra = 0;
514     for (std::set<SUnit*>::iterator I = SU->Preds.begin(),
515            E = SU->Preds.end(); I != E; ++I) {
516       SUnit *PredSU = *I;
517       int PredSethiUllman = CalcNodePriority(PredSU);
518       if (PredSethiUllman > SU->SethiUllman) {
519         SU->SethiUllman = PredSethiUllman;
520         Extra = 0;
521       } else if (PredSethiUllman == SU->SethiUllman)
522         Extra++;
523     }
524
525     if (SU->Node->getOpcode() != ISD::TokenFactor)
526       SU->SethiUllman += Extra;
527     else
528       SU->SethiUllman = (Extra == 1) ? 0 : Extra-1;
529   }
530
531   return SU->SethiUllman;
532 }
533
534 /// CalculatePriorities - Calculate priorities of all scheduling units.
535 void ScheduleDAGList::CalculatePriorities() {
536   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
537     // FIXME: assumes uniform latency for now.
538     SU->Latency = 1;
539     (void)CalcNodePriority(SU);
540     DEBUG(SU->dump(&DAG));
541     DEBUG(std::cerr << "\n");
542   }
543 }
544
545 void ScheduleDAGList::BuildSchedUnits() {
546   // Pass 1: create the SUnit's.
547   for (unsigned i = 0, NC = NodeCount; i < NC; i++) {
548     NodeInfo *NI = &Info[i];
549     SDNode *N = NI->Node;
550     if (isPassiveNode(N))
551       continue;
552
553     SUnit *SU;
554     if (NI->isInGroup()) {
555       if (NI != NI->Group->getBottom())  // Bottom up, so only look at bottom
556         continue;                        // node of the NodeGroup
557
558       SU = NewSUnit(N);
559       // Find the flagged nodes.
560       SDOperand  FlagOp = N->getOperand(N->getNumOperands() - 1);
561       SDNode    *Flag   = FlagOp.Val;
562       unsigned   ResNo  = FlagOp.ResNo;
563       while (Flag->getValueType(ResNo) == MVT::Flag) {
564         NodeInfo *FNI = getNI(Flag);
565         assert(FNI->Group == NI->Group);
566         SU->FlaggedNodes.insert(SU->FlaggedNodes.begin(), Flag);
567         SUnitMap[Flag] = SU;
568
569         FlagOp = Flag->getOperand(Flag->getNumOperands() - 1);
570         Flag   = FlagOp.Val;
571         ResNo  = FlagOp.ResNo;
572       }
573     } else {
574       SU = NewSUnit(N);
575     }
576     SUnitMap[N] = SU;
577   }
578
579   // Pass 2: add the preds, succs, etc.
580   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
581     SDNode   *N  = SU->Node;
582     NodeInfo *NI = getNI(N);
583     
584     if (N->isTargetOpcode() && TII->isTwoAddrInstr(N->getTargetOpcode()))
585       SU->isTwoAddress = true;
586
587     if (NI->isInGroup()) {
588       // Find all predecessors (of the group).
589       NodeGroupOpIterator NGOI(NI);
590       while (!NGOI.isEnd()) {
591         SDOperand Op  = NGOI.next();
592         SDNode   *OpN = Op.Val;
593         MVT::ValueType VT = OpN->getValueType(Op.ResNo);
594         NodeInfo *OpNI = getNI(OpN);
595         if (OpNI->Group != NI->Group && !isPassiveNode(OpN)) {
596           assert(VT != MVT::Flag);
597           SUnit *OpSU = SUnitMap[OpN];
598           if (VT == MVT::Other) {
599             if (SU->ChainPreds.insert(OpSU).second)
600               SU->NumChainPredsLeft++;
601             if (OpSU->ChainSuccs.insert(SU).second)
602               OpSU->NumChainSuccsLeft++;
603           } else {
604             if (SU->Preds.insert(OpSU).second)
605               SU->NumPredsLeft++;
606             if (OpSU->Succs.insert(SU).second)
607               OpSU->NumSuccsLeft++;
608           }
609         }
610       }
611     } else {
612       // Find node predecessors.
613       for (unsigned j = 0, e = N->getNumOperands(); j != e; j++) {
614         SDOperand Op  = N->getOperand(j);
615         SDNode   *OpN = Op.Val;
616         MVT::ValueType VT = OpN->getValueType(Op.ResNo);
617         if (!isPassiveNode(OpN)) {
618           assert(VT != MVT::Flag);
619           SUnit *OpSU = SUnitMap[OpN];
620           if (VT == MVT::Other) {
621             if (SU->ChainPreds.insert(OpSU).second)
622               SU->NumChainPredsLeft++;
623             if (OpSU->ChainSuccs.insert(SU).second)
624               OpSU->NumChainSuccsLeft++;
625           } else {
626             if (SU->Preds.insert(OpSU).second)
627               SU->NumPredsLeft++;
628             if (OpSU->Succs.insert(SU).second)
629               OpSU->NumSuccsLeft++;
630             if (j == 0 && SU->isTwoAddress) 
631               OpSU->isDefNUseOperand = true;
632           }
633         }
634       }
635     }
636   }
637 }
638
639 /// EmitSchedule - Emit the machine code in scheduled order.
640 void ScheduleDAGList::EmitSchedule() {
641   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
642     if (SUnit *SU = Sequence[i]) {
643       for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) {
644         SDNode *N = SU->FlaggedNodes[j];
645         EmitNode(getNI(N));
646       }
647       EmitNode(getNI(SU->Node));
648     } else {
649       // Null SUnit* is a noop.
650       EmitNoop();
651     }
652   }
653 }
654
655 /// dump - dump the schedule.
656 void ScheduleDAGList::dump() const {
657   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
658     if (SUnit *SU = Sequence[i])
659       SU->dump(&DAG, false);
660     else
661       std::cerr << "**** NOOP ****\n";
662   }
663 }
664
665 /// Schedule - Schedule the DAG using list scheduling.
666 /// FIXME: Right now it only supports the burr (bottom up register reducing)
667 /// heuristic.
668 void ScheduleDAGList::Schedule() {
669   DEBUG(std::cerr << "********** List Scheduling **********\n");
670
671   // Build scheduling units.
672   BuildSchedUnits();
673
674   // Calculate node priorities.
675   CalculatePriorities();
676
677   // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate.
678   if (isBottomUp)
679     ListScheduleBottomUp();
680   else
681     ListScheduleTopDown();
682   
683   DEBUG(std::cerr << "*** Final schedule ***\n");
684   DEBUG(dump());
685   DEBUG(std::cerr << "\n");
686   
687   // Emit in scheduled order
688   EmitSchedule();
689 }
690
691 llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG,
692                                                     MachineBasicBlock *BB) {
693   return new ScheduleDAGList(DAG, BB, DAG.getTarget(), true, 
694                              new HazardRecognizer());
695 }
696
697 /// createTDListDAGScheduler - This creates a top-down list scheduler with the
698 /// specified hazard recognizer.
699 ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAG &DAG,
700                                             MachineBasicBlock *BB,
701                                             HazardRecognizer *HR) {
702   return new ScheduleDAGList(DAG, BB, DAG.getTarget(), false, HR);
703 }