fd05980cdc028e6d6c2fc36a0ed07905a828e57b
[oota-llvm.git] / lib / CodeGen / SelectionDAG / ScheduleDAGList.cpp
1 //===---- ScheduleDAGList.cpp - Implement a list scheduler for isel DAG ---===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Evan Cheng and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This implements bottom-up and top-down list schedulers, using standard
11 // algorithms.  The basic approach uses a priority queue of available nodes to
12 // schedule.  One at a time, nodes are taken from the priority queue (thus in
13 // priority order), checked for legality to schedule, and emitted if legal.
14 //
15 // Nodes may not be legal to schedule either due to structural hazards (e.g.
16 // pipeline or resource constraints) or because an input to the instruction has
17 // not completed execution.
18 //
19 //===----------------------------------------------------------------------===//
20
21 #define DEBUG_TYPE "sched"
22 #include "llvm/CodeGen/ScheduleDAG.h"
23 #include "llvm/Target/TargetMachine.h"
24 #include "llvm/Target/TargetInstrInfo.h"
25 #include "llvm/Support/Debug.h"
26 #include "llvm/ADT/Statistic.h"
27 #include <climits>
28 #include <iostream>
29 #include <queue>
30 #include <set>
31 #include <vector>
32 #include "llvm/Support/CommandLine.h"
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
40   /// a 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     short NumPredsLeft;                 // # of preds not scheduled.
49     short NumSuccsLeft;                 // # of succs not scheduled.
50     short NumChainPredsLeft;            // # of chain preds not scheduled.
51     short NumChainSuccsLeft;            // # of chain succs not scheduled.
52     bool isTwoAddress     : 1;          // Is a two-address instruction.
53     bool isDefNUseOperand : 1;          // Is a def&use operand.
54     unsigned short Latency;             // Node latency.
55     unsigned CycleBound;                // Upper/lower cycle to be scheduled at.
56     unsigned NodeNum;                   // Entry # of node in the node vector.
57     
58     SUnit(SDNode *node, unsigned nodenum)
59       : Node(node), NumPredsLeft(0), NumSuccsLeft(0),
60       NumChainPredsLeft(0), NumChainSuccsLeft(0),
61       isTwoAddress(false), isDefNUseOperand(false),
62       Latency(0), CycleBound(0), NodeNum(nodenum) {}
63     
64     void dump(const SelectionDAG *G) const;
65     void dumpAll(const SelectionDAG *G) const;
66   };
67 }
68
69 void SUnit::dump(const SelectionDAG *G) const {
70   std::cerr << "SU: ";
71   Node->dump(G);
72   std::cerr << "\n";
73   if (FlaggedNodes.size() != 0) {
74     for (unsigned i = 0, e = FlaggedNodes.size(); i != e; i++) {
75       std::cerr << "    ";
76       FlaggedNodes[i]->dump(G);
77       std::cerr << "\n";
78     }
79   }
80 }
81
82 void SUnit::dumpAll(const SelectionDAG *G) const {
83   dump(G);
84
85   std::cerr << "  # preds left       : " << NumPredsLeft << "\n";
86   std::cerr << "  # succs left       : " << NumSuccsLeft << "\n";
87   std::cerr << "  # chain preds left : " << NumChainPredsLeft << "\n";
88   std::cerr << "  # chain succs left : " << NumChainSuccsLeft << "\n";
89   std::cerr << "  Latency            : " << Latency << "\n";
90
91   if (Preds.size() != 0) {
92     std::cerr << "  Predecessors:\n";
93     for (std::set<SUnit*>::const_iterator I = Preds.begin(),
94            E = Preds.end(); I != E; ++I) {
95       std::cerr << "    ";
96       (*I)->dump(G);
97     }
98   }
99   if (ChainPreds.size() != 0) {
100     std::cerr << "  Chained Preds:\n";
101     for (std::set<SUnit*>::const_iterator I = ChainPreds.begin(),
102            E = ChainPreds.end(); I != E; ++I) {
103       std::cerr << "    ";
104       (*I)->dump(G);
105     }
106   }
107   if (Succs.size() != 0) {
108     std::cerr << "  Successors:\n";
109     for (std::set<SUnit*>::const_iterator I = Succs.begin(),
110            E = Succs.end(); I != E; ++I) {
111       std::cerr << "    ";
112       (*I)->dump(G);
113     }
114   }
115   if (ChainSuccs.size() != 0) {
116     std::cerr << "  Chained succs:\n";
117     for (std::set<SUnit*>::const_iterator I = ChainSuccs.begin(),
118            E = ChainSuccs.end(); I != E; ++I) {
119       std::cerr << "    ";
120       (*I)->dump(G);
121     }
122   }
123   std::cerr << "\n";
124 }
125
126 //===----------------------------------------------------------------------===//
127 /// SchedulingPriorityQueue - This interface is used to plug different
128 /// priorities computation algorithms into the list scheduler. It implements the
129 /// interface of a standard priority queue, where nodes are inserted in 
130 /// arbitrary order and returned in priority order.  The computation of the
131 /// priority and the representation of the queue are totally up to the
132 /// implementation to decide.
133 /// 
134 namespace {
135 class SchedulingPriorityQueue {
136 public:
137   virtual ~SchedulingPriorityQueue() {}
138   
139   virtual void initNodes(const std::vector<SUnit> &SUnits) = 0;
140   virtual void releaseState() = 0;
141   
142   virtual bool empty() const = 0;
143   virtual void push(SUnit *U) = 0;
144   
145   virtual void push_all(const std::vector<SUnit *> &Nodes) = 0;
146   virtual SUnit *pop() = 0;
147   
148   /// ScheduledNode - As each node is scheduled, this method is invoked.  This
149   /// allows the priority function to adjust the priority of node that have
150   /// already been emitted.
151   virtual void ScheduledNode(SUnit *Node) {}
152 };
153 }
154
155
156
157 namespace {
158 //===----------------------------------------------------------------------===//
159 /// ScheduleDAGList - The actual list scheduler implementation.  This supports
160 /// both top-down and bottom-up scheduling.
161 ///
162 class ScheduleDAGList : public ScheduleDAG {
163 private:
164   // SDNode to SUnit mapping (many to one).
165   std::map<SDNode*, SUnit*> SUnitMap;
166   // The schedule.  Null SUnit*'s represent noop instructions.
167   std::vector<SUnit*> Sequence;
168   // Current scheduling cycle.
169   unsigned CurrCycle;
170   
171   // The scheduling units.
172   std::vector<SUnit> SUnits;
173
174   /// isBottomUp - This is true if the scheduling problem is bottom-up, false if
175   /// it is top-down.
176   bool isBottomUp;
177   
178   /// PriorityQueue - The priority queue to use.
179   SchedulingPriorityQueue *PriorityQueue;
180   
181   /// HazardRec - The hazard recognizer to use.
182   HazardRecognizer *HazardRec;
183   
184 public:
185   ScheduleDAGList(SelectionDAG &dag, MachineBasicBlock *bb,
186                   const TargetMachine &tm, bool isbottomup,
187                   SchedulingPriorityQueue *priorityqueue,
188                   HazardRecognizer *HR)
189     : ScheduleDAG(listSchedulingBURR, dag, bb, tm),
190       CurrCycle(0), isBottomUp(isbottomup), 
191       PriorityQueue(priorityqueue), HazardRec(HR) {
192     }
193
194   ~ScheduleDAGList() {
195     delete HazardRec;
196     delete PriorityQueue;
197   }
198
199   void Schedule();
200
201   void dumpSchedule() const;
202
203 private:
204   SUnit *NewSUnit(SDNode *N);
205   void ReleasePred(SUnit *PredSU, bool isChain = false);
206   void ReleaseSucc(SUnit *SuccSU, bool isChain = false);
207   void ScheduleNodeBottomUp(SUnit *SU);
208   void ScheduleNodeTopDown(SUnit *SU);
209   void ListScheduleTopDown();
210   void ListScheduleBottomUp();
211   void BuildSchedUnits();
212   void EmitSchedule();
213 };
214 }  // end anonymous namespace
215
216 HazardRecognizer::~HazardRecognizer() {}
217
218
219 /// NewSUnit - Creates a new SUnit and return a ptr to it.
220 SUnit *ScheduleDAGList::NewSUnit(SDNode *N) {
221   SUnits.push_back(SUnit(N, SUnits.size()));
222   return &SUnits.back();
223 }
224
225 /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to
226 /// the Available queue is the count reaches zero. Also update its cycle bound.
227 void ScheduleDAGList::ReleasePred(SUnit *PredSU, bool isChain) {
228   // FIXME: the distance between two nodes is not always == the predecessor's
229   // latency. For example, the reader can very well read the register written
230   // by the predecessor later than the issue cycle. It also depends on the
231   // interrupt model (drain vs. freeze).
232   PredSU->CycleBound = std::max(PredSU->CycleBound,CurrCycle + PredSU->Latency);
233
234   if (!isChain)
235     PredSU->NumSuccsLeft--;
236   else
237     PredSU->NumChainSuccsLeft--;
238   
239 #ifndef NDEBUG
240   if (PredSU->NumSuccsLeft < 0 || PredSU->NumChainSuccsLeft < 0) {
241     std::cerr << "*** List scheduling failed! ***\n";
242     PredSU->dump(&DAG);
243     std::cerr << " has been released too many times!\n";
244     assert(0);
245   }
246 #endif
247   
248   if ((PredSU->NumSuccsLeft + PredSU->NumChainSuccsLeft) == 0) {
249     // EntryToken has to go last!  Special case it here.
250     if (PredSU->Node->getOpcode() != ISD::EntryToken)
251       PriorityQueue->push(PredSU);
252   }
253 }
254
255 /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to
256 /// the Available queue is the count reaches zero. Also update its cycle bound.
257 void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain) {
258   // FIXME: the distance between two nodes is not always == the predecessor's
259   // latency. For example, the reader can very well read the register written
260   // by the predecessor later than the issue cycle. It also depends on the
261   // interrupt model (drain vs. freeze).
262   SuccSU->CycleBound = std::max(SuccSU->CycleBound,CurrCycle + SuccSU->Latency);
263   
264   if (!isChain)
265     SuccSU->NumPredsLeft--;
266   else
267     SuccSU->NumChainPredsLeft--;
268   
269 #ifndef NDEBUG
270   if (SuccSU->NumPredsLeft < 0 || SuccSU->NumChainPredsLeft < 0) {
271     std::cerr << "*** List scheduling failed! ***\n";
272     SuccSU->dump(&DAG);
273     std::cerr << " has been released too many times!\n";
274     abort();
275   }
276 #endif
277   
278   if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0)
279     PriorityQueue->push(SuccSU);
280 }
281
282 /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending
283 /// count of its predecessors. If a predecessor pending count is zero, add it to
284 /// the Available queue.
285 void ScheduleDAGList::ScheduleNodeBottomUp(SUnit *SU) {
286   DEBUG(std::cerr << "*** Scheduling: ");
287   DEBUG(SU->dump(&DAG));
288
289   Sequence.push_back(SU);
290
291   // Bottom up: release predecessors
292   for (std::set<SUnit*>::iterator I1 = SU->Preds.begin(),
293          E1 = SU->Preds.end(); I1 != E1; ++I1) {
294     ReleasePred(*I1);
295     SU->NumPredsLeft--;
296   }
297   for (std::set<SUnit*>::iterator I2 = SU->ChainPreds.begin(),
298          E2 = SU->ChainPreds.end(); I2 != E2; ++I2)
299     ReleasePred(*I2, true);
300
301   CurrCycle++;
302 }
303
304 /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending
305 /// count of its successors. If a successor pending count is zero, add it to
306 /// the Available queue.
307 void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU) {
308   DEBUG(std::cerr << "*** Scheduling: ");
309   DEBUG(SU->dump(&DAG));
310   
311   Sequence.push_back(SU);
312   
313   // Bottom up: release successors.
314   for (std::set<SUnit*>::iterator I1 = SU->Succs.begin(),
315        E1 = SU->Succs.end(); I1 != E1; ++I1) {
316     ReleaseSucc(*I1);
317     SU->NumSuccsLeft--;
318   }
319   for (std::set<SUnit*>::iterator I2 = SU->ChainSuccs.begin(),
320        E2 = SU->ChainSuccs.end(); I2 != E2; ++I2)
321     ReleaseSucc(*I2, true);
322   
323   CurrCycle++;
324 }
325
326 /// isReady - True if node's lower cycle bound is less or equal to the current
327 /// scheduling cycle. Always true if all nodes have uniform latency 1.
328 static inline bool isReady(SUnit *SU, unsigned CurrCycle) {
329   return SU->CycleBound <= CurrCycle;
330 }
331
332 /// ListScheduleBottomUp - The main loop of list scheduling for bottom-up
333 /// schedulers.
334 void ScheduleDAGList::ListScheduleBottomUp() {
335   // Add root to Available queue.
336   PriorityQueue->push(SUnitMap[DAG.getRoot().Val]);
337
338   // While Available queue is not empty, grab the node with the highest
339   // priority. If it is not ready put it back. Schedule the node.
340   std::vector<SUnit*> NotReady;
341   while (!PriorityQueue->empty()) {
342     SUnit *CurrNode = PriorityQueue->pop();
343
344     while (!isReady(CurrNode, CurrCycle)) {
345       NotReady.push_back(CurrNode);
346       CurrNode = PriorityQueue->pop();
347     }
348     
349     // Add the nodes that aren't ready back onto the available list.
350     PriorityQueue->push_all(NotReady);
351     NotReady.clear();
352
353     PriorityQueue->ScheduledNode(CurrNode);
354     ScheduleNodeBottomUp(CurrNode);
355   }
356
357   // Add entry node last
358   if (DAG.getEntryNode().Val != DAG.getRoot().Val) {
359     SUnit *Entry = SUnitMap[DAG.getEntryNode().Val];
360     Sequence.push_back(Entry);
361   }
362
363   // Reverse the order if it is bottom up.
364   std::reverse(Sequence.begin(), Sequence.end());
365   
366   
367 #ifndef NDEBUG
368   // Verify that all SUnits were scheduled.
369   bool AnyNotSched = false;
370   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
371     if (SUnits[i].NumSuccsLeft != 0 || SUnits[i].NumChainSuccsLeft != 0) {
372       if (!AnyNotSched)
373         std::cerr << "*** List scheduling failed! ***\n";
374       SUnits[i].dump(&DAG);
375       std::cerr << "has not been scheduled!\n";
376       AnyNotSched = true;
377     }
378   }
379   assert(!AnyNotSched);
380 #endif
381 }
382
383 /// ListScheduleTopDown - The main loop of list scheduling for top-down
384 /// schedulers.
385 void ScheduleDAGList::ListScheduleTopDown() {
386   // Emit the entry node first.
387   SUnit *Entry = SUnitMap[DAG.getEntryNode().Val];
388   ScheduleNodeTopDown(Entry);
389   HazardRec->EmitInstruction(Entry->Node);
390                       
391   // All leaves to Available queue.
392   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
393     // It is available if it has no predecessors.
394     if ((SUnits[i].Preds.size() + SUnits[i].ChainPreds.size()) == 0 &&
395         &SUnits[i] != Entry)
396       PriorityQueue->push(&SUnits[i]);
397   }
398   
399   // While Available queue is not empty, grab the node with the highest
400   // priority. If it is not ready put it back.  Schedule the node.
401   std::vector<SUnit*> NotReady;
402   while (!PriorityQueue->empty()) {
403     SUnit *FoundNode = 0;
404
405     bool HasNoopHazards = false;
406     do {
407       SUnit *CurNode = PriorityQueue->pop();
408       
409       // Get the node represented by this SUnit.
410       SDNode *N = CurNode->Node;
411       // If this is a pseudo op, like copyfromreg, look to see if there is a
412       // real target node flagged to it.  If so, use the target node.
413       for (unsigned i = 0, e = CurNode->FlaggedNodes.size(); 
414            N->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i)
415         N = CurNode->FlaggedNodes[i];
416       
417       HazardRecognizer::HazardType HT = HazardRec->getHazardType(N);
418       if (HT == HazardRecognizer::NoHazard) {
419         FoundNode = CurNode;
420         break;
421       }
422       
423       // Remember if this is a noop hazard.
424       HasNoopHazards |= HT == HazardRecognizer::NoopHazard;
425       
426       NotReady.push_back(CurNode);
427     } while (!PriorityQueue->empty());
428     
429     // Add the nodes that aren't ready back onto the available list.
430     PriorityQueue->push_all(NotReady);
431     NotReady.clear();
432
433     // If we found a node to schedule, do it now.
434     if (FoundNode) {
435       PriorityQueue->ScheduledNode(FoundNode);
436       ScheduleNodeTopDown(FoundNode);
437       HazardRec->EmitInstruction(FoundNode->Node);
438     } else if (!HasNoopHazards) {
439       // Otherwise, we have a pipeline stall, but no other problem, just advance
440       // the current cycle and try again.
441       DEBUG(std::cerr << "*** Advancing cycle, no work to do\n");
442       HazardRec->AdvanceCycle();
443       ++NumStalls;
444     } else {
445       // Otherwise, we have no instructions to issue and we have instructions
446       // that will fault if we don't do this right.  This is the case for
447       // processors without pipeline interlocks and other cases.
448       DEBUG(std::cerr << "*** Emitting noop\n");
449       HazardRec->EmitNoop();
450       Sequence.push_back(0);   // NULL SUnit* -> noop
451       ++NumNoops;
452     }
453   }
454
455 #ifndef NDEBUG
456   // Verify that all SUnits were scheduled.
457   bool AnyNotSched = false;
458   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
459     if (SUnits[i].NumPredsLeft != 0 || SUnits[i].NumChainPredsLeft != 0) {
460       if (!AnyNotSched)
461         std::cerr << "*** List scheduling failed! ***\n";
462       SUnits[i].dump(&DAG);
463       std::cerr << "has not been scheduled!\n";
464       AnyNotSched = true;
465     }
466   }
467   assert(!AnyNotSched);
468 #endif
469 }
470
471
472 void ScheduleDAGList::BuildSchedUnits() {
473   // Reserve entries in the vector for each of the SUnits we are creating.  This
474   // ensure that reallocation of the vector won't happen, so SUnit*'s won't get
475   // invalidated.
476   SUnits.reserve(NodeCount);
477   
478   const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
479
480   // Pass 1: create the SUnit's.
481   for (unsigned i = 0, NC = NodeCount; i < NC; i++) {
482     NodeInfo *NI = &Info[i];
483     SDNode *N = NI->Node;
484     if (isPassiveNode(N))
485       continue;
486
487     SUnit *SU;
488     if (NI->isInGroup()) {
489       if (NI != NI->Group->getBottom())  // Bottom up, so only look at bottom
490         continue;                        // node of the NodeGroup
491
492       SU = NewSUnit(N);
493       // Find the flagged nodes.
494       SDOperand  FlagOp = N->getOperand(N->getNumOperands() - 1);
495       SDNode    *Flag   = FlagOp.Val;
496       unsigned   ResNo  = FlagOp.ResNo;
497       while (Flag->getValueType(ResNo) == MVT::Flag) {
498         NodeInfo *FNI = getNI(Flag);
499         assert(FNI->Group == NI->Group);
500         SU->FlaggedNodes.insert(SU->FlaggedNodes.begin(), Flag);
501         SUnitMap[Flag] = SU;
502
503         FlagOp = Flag->getOperand(Flag->getNumOperands() - 1);
504         Flag   = FlagOp.Val;
505         ResNo  = FlagOp.ResNo;
506       }
507     } else {
508       SU = NewSUnit(N);
509     }
510     SUnitMap[N] = SU;
511
512     // Compute the latency for the node.  We use the sum of the latencies for
513     // all nodes flagged together into this SUnit.
514     if (InstrItins.isEmpty()) {
515       // No latency information.
516       SU->Latency = 1;
517     } else {
518       SU->Latency = 0;
519       if (N->isTargetOpcode()) {
520         unsigned SchedClass = TII->getSchedClass(N->getTargetOpcode());
521         InstrStage *S = InstrItins.begin(SchedClass);
522         InstrStage *E = InstrItins.end(SchedClass);
523         for (; S != E; ++S)
524           SU->Latency += S->Cycles;
525       }
526       for (unsigned i = 0, e = SU->FlaggedNodes.size(); i != e; ++i) {
527         SDNode *FNode = SU->FlaggedNodes[i];
528         if (FNode->isTargetOpcode()) {
529           unsigned SchedClass = TII->getSchedClass(FNode->getTargetOpcode());
530           InstrStage *S = InstrItins.begin(SchedClass);
531           InstrStage *E = InstrItins.end(SchedClass);
532           for (; S != E; ++S)
533             SU->Latency += S->Cycles;
534         }
535       }
536     }
537   }
538
539   // Pass 2: add the preds, succs, etc.
540   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
541     SUnit *SU = &SUnits[i];
542     SDNode   *N  = SU->Node;
543     NodeInfo *NI = getNI(N);
544     
545     if (N->isTargetOpcode() && TII->isTwoAddrInstr(N->getTargetOpcode()))
546       SU->isTwoAddress = true;
547
548     if (NI->isInGroup()) {
549       // Find all predecessors (of the group).
550       NodeGroupOpIterator NGOI(NI);
551       while (!NGOI.isEnd()) {
552         SDOperand Op  = NGOI.next();
553         SDNode   *OpN = Op.Val;
554         MVT::ValueType VT = OpN->getValueType(Op.ResNo);
555         NodeInfo *OpNI = getNI(OpN);
556         if (OpNI->Group != NI->Group && !isPassiveNode(OpN)) {
557           assert(VT != MVT::Flag);
558           SUnit *OpSU = SUnitMap[OpN];
559           if (VT == MVT::Other) {
560             if (SU->ChainPreds.insert(OpSU).second)
561               SU->NumChainPredsLeft++;
562             if (OpSU->ChainSuccs.insert(SU).second)
563               OpSU->NumChainSuccsLeft++;
564           } else {
565             if (SU->Preds.insert(OpSU).second)
566               SU->NumPredsLeft++;
567             if (OpSU->Succs.insert(SU).second)
568               OpSU->NumSuccsLeft++;
569           }
570         }
571       }
572     } else {
573       // Find node predecessors.
574       for (unsigned j = 0, e = N->getNumOperands(); j != e; j++) {
575         SDOperand Op  = N->getOperand(j);
576         SDNode   *OpN = Op.Val;
577         MVT::ValueType VT = OpN->getValueType(Op.ResNo);
578         if (!isPassiveNode(OpN)) {
579           assert(VT != MVT::Flag);
580           SUnit *OpSU = SUnitMap[OpN];
581           if (VT == MVT::Other) {
582             if (SU->ChainPreds.insert(OpSU).second)
583               SU->NumChainPredsLeft++;
584             if (OpSU->ChainSuccs.insert(SU).second)
585               OpSU->NumChainSuccsLeft++;
586           } else {
587             if (SU->Preds.insert(OpSU).second)
588               SU->NumPredsLeft++;
589             if (OpSU->Succs.insert(SU).second)
590               OpSU->NumSuccsLeft++;
591             if (j == 0 && SU->isTwoAddress) 
592               OpSU->isDefNUseOperand = true;
593           }
594         }
595       }
596     }
597     
598     DEBUG(SU->dumpAll(&DAG));
599   }
600 }
601
602 /// EmitSchedule - Emit the machine code in scheduled order.
603 void ScheduleDAGList::EmitSchedule() {
604   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
605     if (SUnit *SU = Sequence[i]) {
606       for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) {
607         SDNode *N = SU->FlaggedNodes[j];
608         EmitNode(getNI(N));
609       }
610       EmitNode(getNI(SU->Node));
611     } else {
612       // Null SUnit* is a noop.
613       EmitNoop();
614     }
615   }
616 }
617
618 /// dump - dump the schedule.
619 void ScheduleDAGList::dumpSchedule() const {
620   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
621     if (SUnit *SU = Sequence[i])
622       SU->dump(&DAG);
623     else
624       std::cerr << "**** NOOP ****\n";
625   }
626 }
627
628 /// Schedule - Schedule the DAG using list scheduling.
629 /// FIXME: Right now it only supports the burr (bottom up register reducing)
630 /// heuristic.
631 void ScheduleDAGList::Schedule() {
632   DEBUG(std::cerr << "********** List Scheduling **********\n");
633
634   // Build scheduling units.
635   BuildSchedUnits();
636   
637   PriorityQueue->initNodes(SUnits);
638   
639   // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate.
640   if (isBottomUp)
641     ListScheduleBottomUp();
642   else
643     ListScheduleTopDown();
644
645   PriorityQueue->releaseState();
646
647   DEBUG(std::cerr << "*** Final schedule ***\n");
648   DEBUG(dumpSchedule());
649   DEBUG(std::cerr << "\n");
650   
651   // Emit in scheduled order
652   EmitSchedule();
653 }
654
655 //===----------------------------------------------------------------------===//
656 //                RegReductionPriorityQueue Implementation
657 //===----------------------------------------------------------------------===//
658 //
659 // This is a SchedulingPriorityQueue that schedules using Sethi Ullman numbers
660 // to reduce register pressure.
661 // 
662 namespace {
663   class RegReductionPriorityQueue;
664   
665   /// Sorting functions for the Available queue.
666   struct ls_rr_sort : public std::binary_function<SUnit*, SUnit*, bool> {
667     RegReductionPriorityQueue *SPQ;
668     ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {}
669     ls_rr_sort(const ls_rr_sort &RHS) : SPQ(RHS.SPQ) {}
670     
671     bool operator()(const SUnit* left, const SUnit* right) const;
672   };
673 }  // end anonymous namespace
674
675 namespace {
676   class RegReductionPriorityQueue : public SchedulingPriorityQueue {
677     // SUnits - The SUnits for the current graph.
678     const std::vector<SUnit> *SUnits;
679     
680     // SethiUllmanNumbers - The SethiUllman number for each node.
681     std::vector<int> SethiUllmanNumbers;
682     
683     std::priority_queue<SUnit*, std::vector<SUnit*>, ls_rr_sort> Queue;
684   public:
685     RegReductionPriorityQueue() : Queue(ls_rr_sort(this)) {
686     }
687     
688     void initNodes(const std::vector<SUnit> &sunits) {
689       SUnits = &sunits;
690       // Calculate node priorities.
691       CalculatePriorities();
692     }
693     void releaseState() {
694       SUnits = 0;
695       SethiUllmanNumbers.clear();
696     }
697     
698     unsigned getSethiUllmanNumber(unsigned NodeNum) const {
699       assert(NodeNum < SethiUllmanNumbers.size());
700       return SethiUllmanNumbers[NodeNum];
701     }
702     
703     bool empty() const { return Queue.empty(); }
704     
705     void push(SUnit *U) {
706       Queue.push(U);
707     }
708     void push_all(const std::vector<SUnit *> &Nodes) {
709       for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
710         Queue.push(Nodes[i]);
711     }
712     
713     SUnit *pop() {
714       SUnit *V = Queue.top();
715       Queue.pop();
716       return V;
717     }
718   private:
719     void CalculatePriorities();
720     int CalcNodePriority(const SUnit *SU);
721   };
722 }
723
724 bool ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
725   unsigned LeftNum  = left->NodeNum;
726   unsigned RightNum = right->NodeNum;
727   
728   int LBonus = (int)left ->isDefNUseOperand;
729   int RBonus = (int)right->isDefNUseOperand;
730   
731   // Special tie breaker: if two nodes share a operand, the one that
732   // use it as a def&use operand is preferred.
733   if (left->isTwoAddress && !right->isTwoAddress) {
734     SDNode *DUNode = left->Node->getOperand(0).Val;
735     if (DUNode->isOperand(right->Node))
736       LBonus++;
737   }
738   if (!left->isTwoAddress && right->isTwoAddress) {
739     SDNode *DUNode = right->Node->getOperand(0).Val;
740     if (DUNode->isOperand(left->Node))
741       RBonus++;
742   }
743   
744   // Priority1 is just the number of live range genned.
745   int LPriority1 = left ->NumPredsLeft - LBonus;
746   int RPriority1 = right->NumPredsLeft - RBonus;
747   int LPriority2 = SPQ->getSethiUllmanNumber(LeftNum) + LBonus;
748   int RPriority2 = SPQ->getSethiUllmanNumber(RightNum) + RBonus;
749   
750   if (LPriority1 > RPriority1)
751     return true;
752   else if (LPriority1 == RPriority1)
753     if (LPriority2 < RPriority2)
754       return true;
755     else if (LPriority2 == RPriority2)
756       if (left->CycleBound > right->CycleBound) 
757         return true;
758   
759   return false;
760 }
761
762
763 /// CalcNodePriority - Priority is the Sethi Ullman number. 
764 /// Smaller number is the higher priority.
765 int RegReductionPriorityQueue::CalcNodePriority(const SUnit *SU) {
766   int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum];
767   if (SethiUllmanNumber != INT_MIN)
768     return SethiUllmanNumber;
769   
770   if (SU->Preds.size() == 0) {
771     SethiUllmanNumber = 1;
772   } else {
773     int Extra = 0;
774     for (std::set<SUnit*>::const_iterator I = SU->Preds.begin(),
775          E = SU->Preds.end(); I != E; ++I) {
776       SUnit *PredSU = *I;
777       int PredSethiUllman = CalcNodePriority(PredSU);
778       if (PredSethiUllman > SethiUllmanNumber) {
779         SethiUllmanNumber = PredSethiUllman;
780         Extra = 0;
781       } else if (PredSethiUllman == SethiUllmanNumber)
782         Extra++;
783     }
784     
785     if (SU->Node->getOpcode() != ISD::TokenFactor)
786       SethiUllmanNumber += Extra;
787     else
788       SethiUllmanNumber = (Extra == 1) ? 0 : Extra-1;
789   }
790   
791   return SethiUllmanNumber;
792 }
793
794 /// CalculatePriorities - Calculate priorities of all scheduling units.
795 void RegReductionPriorityQueue::CalculatePriorities() {
796   SethiUllmanNumbers.assign(SUnits->size(), INT_MIN);
797   
798   for (unsigned i = 0, e = SUnits->size(); i != e; ++i)
799     CalcNodePriority(&(*SUnits)[i]);
800 }
801
802 //===----------------------------------------------------------------------===//
803 //                    LatencyPriorityQueue Implementation
804 //===----------------------------------------------------------------------===//
805 //
806 // This is a SchedulingPriorityQueue that schedules using latency information to
807 // reduce the length of the critical path through the basic block.
808 // 
809 namespace {
810   class LatencyPriorityQueue;
811   
812   /// Sorting functions for the Available queue.
813   struct latency_sort : public std::binary_function<SUnit*, SUnit*, bool> {
814     LatencyPriorityQueue *PQ;
815     latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {}
816     latency_sort(const latency_sort &RHS) : PQ(RHS.PQ) {}
817     
818     bool operator()(const SUnit* left, const SUnit* right) const;
819   };
820 }  // end anonymous namespace
821
822 namespace {
823   class LatencyPriorityQueue : public SchedulingPriorityQueue {
824     // SUnits - The SUnits for the current graph.
825     const std::vector<SUnit> *SUnits;
826     
827     // Latencies - The latency (max of latency from this node to the bb exit)
828     // for each node.
829     std::vector<int> Latencies;
830     
831     std::priority_queue<SUnit*, std::vector<SUnit*>, latency_sort> Queue;
832 public:
833     LatencyPriorityQueue() : Queue(latency_sort(this)) {
834     }
835     
836     void initNodes(const std::vector<SUnit> &sunits) {
837       SUnits = &sunits;
838       // Calculate node priorities.
839       CalculatePriorities();
840     }
841     void releaseState() {
842       SUnits = 0;
843       Latencies.clear();
844     }
845     
846     unsigned getLatency(unsigned NodeNum) const {
847       assert(NodeNum < Latencies.size());
848       return Latencies[NodeNum];
849     }
850     
851     bool empty() const { return Queue.empty(); }
852     
853     void push(SUnit *U) {
854       Queue.push(U);
855     }
856     void push_all(const std::vector<SUnit *> &Nodes) {
857       for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
858         Queue.push(Nodes[i]);
859     }
860     
861     SUnit *pop() {
862       SUnit *V = Queue.top();
863       Queue.pop();
864       return V;
865     }
866 private:
867     void CalculatePriorities();
868     int CalcLatency(const SUnit &SU);
869   };
870 }
871
872 bool latency_sort::operator()(const SUnit *LHS, const SUnit *RHS) const {
873   unsigned LHSNum = LHS->NodeNum;
874   unsigned RHSNum = RHS->NodeNum;
875   
876   return PQ->getLatency(LHSNum) < PQ->getLatency(RHSNum);
877 }
878
879
880 /// CalcNodePriority - Calculate the maximal path from the node to the exit.
881 ///
882 int LatencyPriorityQueue::CalcLatency(const SUnit &SU) {
883   int &Latency = Latencies[SU.NodeNum];
884   if (Latency != -1)
885     return Latency;
886   
887   int MaxSuccLatency = 0;
888   for (std::set<SUnit*>::const_iterator I = SU.Succs.begin(),
889        E = SU.Succs.end(); I != E; ++I)
890     MaxSuccLatency = std::max(MaxSuccLatency, CalcLatency(**I));
891
892   for (std::set<SUnit*>::const_iterator I = SU.ChainSuccs.begin(),
893        E = SU.ChainSuccs.end(); I != E; ++I)
894     MaxSuccLatency = std::max(MaxSuccLatency, CalcLatency(**I));
895
896   return Latency = MaxSuccLatency + SU.Latency;
897 }
898
899 /// CalculatePriorities - Calculate priorities of all scheduling units.
900 void LatencyPriorityQueue::CalculatePriorities() {
901   Latencies.assign(SUnits->size(), -1);
902   
903   for (unsigned i = 0, e = SUnits->size(); i != e; ++i)
904     CalcLatency((*SUnits)[i]);
905 }
906
907
908 //===----------------------------------------------------------------------===//
909 //                         Public Constructor Functions
910 //===----------------------------------------------------------------------===//
911
912 llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG,
913                                                     MachineBasicBlock *BB) {
914   return new ScheduleDAGList(DAG, BB, DAG.getTarget(), true, 
915                              new RegReductionPriorityQueue(),
916                              new HazardRecognizer());
917 }
918
919 /// createTDListDAGScheduler - This creates a top-down list scheduler with the
920 /// specified hazard recognizer.
921 ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAG &DAG,
922                                             MachineBasicBlock *BB,
923                                             HazardRecognizer *HR) {
924   return new ScheduleDAGList(DAG, BB, DAG.getTarget(), false,
925                              new LatencyPriorityQueue(),
926                              HR);
927 }