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