Fix some formatting, when looking for hazards, prefer target nodes over
[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 *CurNode = Available.top();
439       Available.pop();
440       
441       // Get the node represented by this SUnit.
442       SDNode *N = CurNode->Node;
443       // If this is a pseudo op, like copyfromreg, look to see if there is a
444       // real target node flagged to it.  If so, use the target node.
445       for (unsigned i = 0, e = CurNode->FlaggedNodes.size(); 
446            N->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i)
447         N = CurNode->FlaggedNodes[i];
448       
449       HazardRecognizer::HazardType HT = HazardRec.getHazardType(N);
450       if (HT == HazardRecognizer::NoHazard) {
451         FoundNode = CurNode;
452         break;
453       }
454       
455       // Remember if this is a noop hazard.
456       HasNoopHazards |= HT == HazardRecognizer::NoopHazard;
457       
458       NotReady.push_back(CurNode);
459     } while (!Available.empty());
460     
461     // Add the nodes that aren't ready back onto the available list.
462     while (!NotReady.empty()) {
463       Available.push(NotReady.back());
464       NotReady.pop_back();
465     }
466
467     // If we found a node to schedule, do it now.
468     if (FoundNode) {
469       ScheduleNodeTopDown(Available, FoundNode);
470       HazardRec.EmitInstruction(FoundNode->Node);
471     } else if (!HasNoopHazards) {
472       // Otherwise, we have a pipeline stall, but no other problem, just advance
473       // the current cycle and try again.
474       DEBUG(std::cerr << "*** Advancing cycle, no work to do\n");
475       HazardRec.AdvanceCycle();
476       ++NumStalls;
477     } else {
478       // Otherwise, we have no instructions to issue and we have instructions
479       // that will fault if we don't do this right.  This is the case for
480       // processors without pipeline interlocks and other cases.
481       DEBUG(std::cerr << "*** Emitting noop\n");
482       HazardRec.EmitNoop();
483       Sequence.push_back(0);   // NULL SUnit* -> noop
484       ++NumNoops;
485     }
486   }
487
488 #ifndef NDEBUG
489   // Verify that all SUnits were scheduled.
490   bool AnyNotSched = false;
491   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
492     if (SU->NumPredsLeft != 0 || SU->NumChainPredsLeft != 0) {
493       if (!AnyNotSched)
494         std::cerr << "*** List scheduling failed! ***\n";
495       SU->dump(&DAG);
496       std::cerr << "has not been scheduled!\n";
497       AnyNotSched = true;
498     }
499   }
500   assert(!AnyNotSched);
501 #endif
502 }
503
504
505 /// CalcNodePriority - Priority is the Sethi Ullman number. 
506 /// Smaller number is the higher priority.
507 int ScheduleDAGList::CalcNodePriority(SUnit *SU) {
508   if (SU->SethiUllman != INT_MIN)
509     return SU->SethiUllman;
510
511   if (SU->Preds.size() == 0) {
512     SU->SethiUllman = 1;
513   } else {
514     int Extra = 0;
515     for (std::set<SUnit*>::iterator I = SU->Preds.begin(),
516            E = SU->Preds.end(); I != E; ++I) {
517       SUnit *PredSU = *I;
518       int PredSethiUllman = CalcNodePriority(PredSU);
519       if (PredSethiUllman > SU->SethiUllman) {
520         SU->SethiUllman = PredSethiUllman;
521         Extra = 0;
522       } else if (PredSethiUllman == SU->SethiUllman)
523         Extra++;
524     }
525
526     if (SU->Node->getOpcode() != ISD::TokenFactor)
527       SU->SethiUllman += Extra;
528     else
529       SU->SethiUllman = (Extra == 1) ? 0 : Extra-1;
530   }
531
532   return SU->SethiUllman;
533 }
534
535 /// CalculatePriorities - Calculate priorities of all scheduling units.
536 void ScheduleDAGList::CalculatePriorities() {
537   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
538     // FIXME: assumes uniform latency for now.
539     SU->Latency = 1;
540     (void)CalcNodePriority(SU);
541     DEBUG(SU->dump(&DAG));
542     DEBUG(std::cerr << "\n");
543   }
544 }
545
546 void ScheduleDAGList::BuildSchedUnits() {
547   // Pass 1: create the SUnit's.
548   for (unsigned i = 0, NC = NodeCount; i < NC; i++) {
549     NodeInfo *NI = &Info[i];
550     SDNode *N = NI->Node;
551     if (isPassiveNode(N))
552       continue;
553
554     SUnit *SU;
555     if (NI->isInGroup()) {
556       if (NI != NI->Group->getBottom())  // Bottom up, so only look at bottom
557         continue;                        // node of the NodeGroup
558
559       SU = NewSUnit(N);
560       // Find the flagged nodes.
561       SDOperand  FlagOp = N->getOperand(N->getNumOperands() - 1);
562       SDNode    *Flag   = FlagOp.Val;
563       unsigned   ResNo  = FlagOp.ResNo;
564       while (Flag->getValueType(ResNo) == MVT::Flag) {
565         NodeInfo *FNI = getNI(Flag);
566         assert(FNI->Group == NI->Group);
567         SU->FlaggedNodes.insert(SU->FlaggedNodes.begin(), Flag);
568         SUnitMap[Flag] = SU;
569
570         FlagOp = Flag->getOperand(Flag->getNumOperands() - 1);
571         Flag   = FlagOp.Val;
572         ResNo  = FlagOp.ResNo;
573       }
574     } else {
575       SU = NewSUnit(N);
576     }
577     SUnitMap[N] = SU;
578   }
579
580   // Pass 2: add the preds, succs, etc.
581   for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) {
582     SDNode   *N  = SU->Node;
583     NodeInfo *NI = getNI(N);
584     
585     if (N->isTargetOpcode() && TII->isTwoAddrInstr(N->getTargetOpcode()))
586       SU->isTwoAddress = true;
587
588     if (NI->isInGroup()) {
589       // Find all predecessors (of the group).
590       NodeGroupOpIterator NGOI(NI);
591       while (!NGOI.isEnd()) {
592         SDOperand Op  = NGOI.next();
593         SDNode   *OpN = Op.Val;
594         MVT::ValueType VT = OpN->getValueType(Op.ResNo);
595         NodeInfo *OpNI = getNI(OpN);
596         if (OpNI->Group != NI->Group && !isPassiveNode(OpN)) {
597           assert(VT != MVT::Flag);
598           SUnit *OpSU = SUnitMap[OpN];
599           if (VT == MVT::Other) {
600             if (SU->ChainPreds.insert(OpSU).second)
601               SU->NumChainPredsLeft++;
602             if (OpSU->ChainSuccs.insert(SU).second)
603               OpSU->NumChainSuccsLeft++;
604           } else {
605             if (SU->Preds.insert(OpSU).second)
606               SU->NumPredsLeft++;
607             if (OpSU->Succs.insert(SU).second)
608               OpSU->NumSuccsLeft++;
609           }
610         }
611       }
612     } else {
613       // Find node predecessors.
614       for (unsigned j = 0, e = N->getNumOperands(); j != e; j++) {
615         SDOperand Op  = N->getOperand(j);
616         SDNode   *OpN = Op.Val;
617         MVT::ValueType VT = OpN->getValueType(Op.ResNo);
618         if (!isPassiveNode(OpN)) {
619           assert(VT != MVT::Flag);
620           SUnit *OpSU = SUnitMap[OpN];
621           if (VT == MVT::Other) {
622             if (SU->ChainPreds.insert(OpSU).second)
623               SU->NumChainPredsLeft++;
624             if (OpSU->ChainSuccs.insert(SU).second)
625               OpSU->NumChainSuccsLeft++;
626           } else {
627             if (SU->Preds.insert(OpSU).second)
628               SU->NumPredsLeft++;
629             if (OpSU->Succs.insert(SU).second)
630               OpSU->NumSuccsLeft++;
631             if (j == 0 && SU->isTwoAddress) 
632               OpSU->isDefNUseOperand = true;
633           }
634         }
635       }
636     }
637   }
638 }
639
640 /// EmitSchedule - Emit the machine code in scheduled order.
641 void ScheduleDAGList::EmitSchedule() {
642   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
643     if (SUnit *SU = Sequence[i]) {
644       for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) {
645         SDNode *N = SU->FlaggedNodes[j];
646         EmitNode(getNI(N));
647       }
648       EmitNode(getNI(SU->Node));
649     } else {
650       // Null SUnit* is a noop.
651       EmitNoop();
652     }
653   }
654 }
655
656 /// dump - dump the schedule.
657 void ScheduleDAGList::dump() const {
658   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
659     if (SUnit *SU = Sequence[i])
660       SU->dump(&DAG, false);
661     else
662       std::cerr << "**** NOOP ****\n";
663   }
664 }
665
666 /// Schedule - Schedule the DAG using list scheduling.
667 /// FIXME: Right now it only supports the burr (bottom up register reducing)
668 /// heuristic.
669 void ScheduleDAGList::Schedule() {
670   DEBUG(std::cerr << "********** List Scheduling **********\n");
671
672   // Build scheduling units.
673   BuildSchedUnits();
674
675   // Calculate node priorities.
676   CalculatePriorities();
677
678   // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate.
679   if (isBottomUp)
680     ListScheduleBottomUp();
681   else
682     ListScheduleTopDown();
683   
684   DEBUG(std::cerr << "*** Final schedule ***\n");
685   DEBUG(dump());
686   DEBUG(std::cerr << "\n");
687   
688   // Emit in scheduled order
689   EmitSchedule();
690 }
691
692 llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG,
693                                                     MachineBasicBlock *BB) {
694   HazardRecognizer HR;
695   return new ScheduleDAGList(DAG, BB, DAG.getTarget(), true, HR);
696 }
697
698 /// createTDListDAGScheduler - This creates a top-down list scheduler with the
699 /// specified hazard recognizer.
700 ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAG &DAG,
701                                             MachineBasicBlock *BB,
702                                             HazardRecognizer &HR) {
703   return new ScheduleDAGList(DAG, BB, DAG.getTarget(), false, HR);
704 }