0ef246b8eba56fe94b1c890f40f711d021ba5959
[oota-llvm.git] / lib / CodeGen / SelectionDAG / ScheduleDAGRRList.cpp
1 //===----- ScheduleDAGList.cpp - Reg pressure reduction list scheduler ----===//
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 register pressure reduction list
11 // schedulers, using standard algorithms.  The basic approach uses a priority
12 // queue of available nodes to schedule.  One at a time, nodes are taken from
13 // the priority queue (thus in priority order), checked for legality to
14 // schedule, and emitted if legal.
15 //
16 //===----------------------------------------------------------------------===//
17
18 #define DEBUG_TYPE "sched"
19 #include "llvm/CodeGen/ScheduleDAG.h"
20 #include "llvm/CodeGen/SSARegMap.h"
21 #include "llvm/Target/MRegisterInfo.h"
22 #include "llvm/Target/TargetData.h"
23 #include "llvm/Target/TargetMachine.h"
24 #include "llvm/Target/TargetInstrInfo.h"
25 #include "llvm/Support/Debug.h"
26 #include "llvm/Support/Visibility.h"
27 #include "llvm/ADT/Statistic.h"
28 #include <climits>
29 #include <iostream>
30 #include <queue>
31 #include "llvm/Support/CommandLine.h"
32 using namespace llvm;
33
34 namespace {
35 //===----------------------------------------------------------------------===//
36 /// ScheduleDAGRRList - The actual register reduction list scheduler
37 /// implementation.  This supports both top-down and bottom-up scheduling.
38 ///
39
40 class VISIBILITY_HIDDEN ScheduleDAGRRList : public ScheduleDAG {
41 private:
42   /// isBottomUp - This is true if the scheduling problem is bottom-up, false if
43   /// it is top-down.
44   bool isBottomUp;
45   
46   /// AvailableQueue - The priority queue to use for the available SUnits.
47   ///
48   SchedulingPriorityQueue *AvailableQueue;
49
50 public:
51   ScheduleDAGRRList(SelectionDAG &dag, MachineBasicBlock *bb,
52                   const TargetMachine &tm, bool isbottomup,
53                   SchedulingPriorityQueue *availqueue)
54     : ScheduleDAG(dag, bb, tm), isBottomUp(isbottomup),
55       AvailableQueue(availqueue) {
56     }
57
58   ~ScheduleDAGRRList() {
59     delete AvailableQueue;
60   }
61
62   void Schedule();
63
64 private:
65   void ReleasePred(SUnit *PredSU, bool isChain, unsigned CurCycle);
66   void ReleaseSucc(SUnit *SuccSU, bool isChain, unsigned CurCycle);
67   void ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle);
68   void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle);
69   void ListScheduleTopDown();
70   void ListScheduleBottomUp();
71   void CommuteNodesToReducePressure();
72 };
73 }  // end anonymous namespace
74
75
76 /// Schedule - Schedule the DAG using list scheduling.
77 void ScheduleDAGRRList::Schedule() {
78   DEBUG(std::cerr << "********** List Scheduling **********\n");
79   
80   // Build scheduling units.
81   BuildSchedUnits();
82
83   CalculateDepths();
84   CalculateHeights();
85   DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
86         SUnits[su].dumpAll(&DAG));
87
88   AvailableQueue->initNodes(SUnits);
89
90   // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate.
91   if (isBottomUp)
92     ListScheduleBottomUp();
93   else
94     ListScheduleTopDown();
95   
96   AvailableQueue->releaseState();
97
98   CommuteNodesToReducePressure();
99   
100   DEBUG(std::cerr << "*** Final schedule ***\n");
101   DEBUG(dumpSchedule());
102   DEBUG(std::cerr << "\n");
103   
104   // Emit in scheduled order
105   EmitSchedule();
106 }
107
108 /// CommuteNodesToReducePressure - Is a node is two-address and commutable, and
109 /// it is not the last use of its first operand, add it to the CommuteSet if
110 /// possible. It will be commuted when it is translated to a MI.
111 void ScheduleDAGRRList::CommuteNodesToReducePressure() {
112   std::set<SUnit *> OperandSeen;
113   for (unsigned i = Sequence.size()-1; i != 0; --i) {  // Ignore first node.
114     SUnit *SU = Sequence[i];
115     if (!SU) continue;
116     if (SU->isTwoAddress && SU->isCommutable) {
117       SDNode *OpN = SU->Node->getOperand(0).Val;
118       SUnit *OpSU = SUnitMap[OpN];
119       if (OpSU && OperandSeen.count(OpSU) == 1) {
120         // Ok, so SU is not the last use of OpSU, but SU is two-address so
121         // it will clobber OpSU. Try to commute it if possible.
122         bool DoCommute = true;
123         for (unsigned j = 1, e = SU->Node->getNumOperands(); j != e; ++j) {
124           OpN = SU->Node->getOperand(j).Val;
125           OpSU = SUnitMap[OpN];
126           if (OpSU && OperandSeen.count(OpSU) == 1) {
127             DoCommute = false;
128             break;
129           }
130         }
131         if (DoCommute)
132           CommuteSet.insert(SU->Node);
133       }
134     }
135
136     for (std::set<std::pair<SUnit*, bool> >::iterator I = SU->Preds.begin(),
137            E = SU->Preds.end(); I != E; ++I) {
138       if (!I->second)
139         OperandSeen.insert(I->first);
140     }
141   }
142 }
143
144 //===----------------------------------------------------------------------===//
145 //  Bottom-Up Scheduling
146 //===----------------------------------------------------------------------===//
147
148 static const TargetRegisterClass *getRegClass(SUnit *SU,
149                                               const TargetInstrInfo *TII,
150                                               const MRegisterInfo *MRI,
151                                               SSARegMap *RegMap) {
152   if (SU->Node->isTargetOpcode()) {
153     unsigned Opc = SU->Node->getTargetOpcode();
154     const TargetInstrDescriptor &II = TII->get(Opc);
155     return II.OpInfo->RegClass;
156   } else {
157     assert(SU->Node->getOpcode() == ISD::CopyFromReg);
158     unsigned SrcReg = cast<RegisterSDNode>(SU->Node->getOperand(1))->getReg();
159     if (MRegisterInfo::isVirtualRegister(SrcReg))
160       return RegMap->getRegClass(SrcReg);
161     else {
162       for (MRegisterInfo::regclass_iterator I = MRI->regclass_begin(),
163              E = MRI->regclass_end(); I != E; ++I)
164         if ((*I)->hasType(SU->Node->getValueType(0)) &&
165             (*I)->contains(SrcReg))
166           return *I;
167       assert(false && "Couldn't find register class for reg copy!");
168     }
169     return NULL;
170   }
171 }
172
173 static unsigned getNumResults(SUnit *SU) {
174   unsigned NumResults = 0;
175   for (unsigned i = 0, e = SU->Node->getNumValues(); i != e; ++i) {
176     MVT::ValueType VT = SU->Node->getValueType(i);
177     if (VT != MVT::Other && VT != MVT::Flag)
178       NumResults++;
179   }
180   return NumResults;
181 }
182
183 /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to
184 /// the Available queue is the count reaches zero. Also update its cycle bound.
185 void ScheduleDAGRRList::ReleasePred(SUnit *PredSU, bool isChain, 
186                                     unsigned CurCycle) {
187   // FIXME: the distance between two nodes is not always == the predecessor's
188   // latency. For example, the reader can very well read the register written
189   // by the predecessor later than the issue cycle. It also depends on the
190   // interrupt model (drain vs. freeze).
191   PredSU->CycleBound = std::max(PredSU->CycleBound, CurCycle + PredSU->Latency);
192
193   if (!isChain)
194     PredSU->NumSuccsLeft--;
195   else
196     PredSU->NumChainSuccsLeft--;
197   
198 #ifndef NDEBUG
199   if (PredSU->NumSuccsLeft < 0 || PredSU->NumChainSuccsLeft < 0) {
200     std::cerr << "*** List scheduling failed! ***\n";
201     PredSU->dump(&DAG);
202     std::cerr << " has been released too many times!\n";
203     assert(0);
204   }
205 #endif
206   
207   if ((PredSU->NumSuccsLeft + PredSU->NumChainSuccsLeft) == 0) {
208     // EntryToken has to go last!  Special case it here.
209     if (PredSU->Node->getOpcode() != ISD::EntryToken) {
210       PredSU->isAvailable = true;
211       AvailableQueue->push(PredSU);
212     }
213   }
214 }
215
216 /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending
217 /// count of its predecessors. If a predecessor pending count is zero, add it to
218 /// the Available queue.
219 void ScheduleDAGRRList::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) {
220   DEBUG(std::cerr << "*** Scheduling [" << CurCycle << "]: ");
221   DEBUG(SU->dump(&DAG));
222   SU->Cycle = CurCycle;
223
224   AvailableQueue->ScheduledNode(SU);
225   Sequence.push_back(SU);
226
227   // Bottom up: release predecessors
228   for (std::set<std::pair<SUnit*, bool> >::iterator I = SU->Preds.begin(),
229          E = SU->Preds.end(); I != E; ++I)
230     ReleasePred(I->first, I->second, CurCycle);
231   SU->isScheduled = true;
232 }
233
234 /// isReady - True if node's lower cycle bound is less or equal to the current
235 /// scheduling cycle. Always true if all nodes have uniform latency 1.
236 static inline bool isReady(SUnit *SU, unsigned CurCycle) {
237   return SU->CycleBound <= CurCycle;
238 }
239
240 /// ListScheduleBottomUp - The main loop of list scheduling for bottom-up
241 /// schedulers.
242 void ScheduleDAGRRList::ListScheduleBottomUp() {
243   unsigned CurCycle = 0;
244   // Add root to Available queue.
245   AvailableQueue->push(SUnitMap[DAG.getRoot().Val]);
246
247   // While Available queue is not empty, grab the node with the highest
248   // priority. If it is not ready put it back. Schedule the node.
249   std::vector<SUnit*> NotReady;
250   SUnit *CurNode = NULL;
251   while (!AvailableQueue->empty()) {
252     SUnit *CurNode = AvailableQueue->pop();
253     while (CurNode && !isReady(CurNode, CurCycle)) {
254       NotReady.push_back(CurNode);
255       CurNode = AvailableQueue->pop();
256     }
257     
258     // Add the nodes that aren't ready back onto the available list.
259     AvailableQueue->push_all(NotReady);
260     NotReady.clear();
261
262     if (CurNode != NULL)
263       ScheduleNodeBottomUp(CurNode, CurCycle);
264     CurCycle++;
265   }
266
267   // Add entry node last
268   if (DAG.getEntryNode().Val != DAG.getRoot().Val) {
269     SUnit *Entry = SUnitMap[DAG.getEntryNode().Val];
270     Sequence.push_back(Entry);
271   }
272
273   // Reverse the order if it is bottom up.
274   std::reverse(Sequence.begin(), Sequence.end());
275   
276   
277 #ifndef NDEBUG
278   // Verify that all SUnits were scheduled.
279   bool AnyNotSched = false;
280   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
281     if (SUnits[i].NumSuccsLeft != 0 || SUnits[i].NumChainSuccsLeft != 0) {
282       if (!AnyNotSched)
283         std::cerr << "*** List scheduling failed! ***\n";
284       SUnits[i].dump(&DAG);
285       std::cerr << "has not been scheduled!\n";
286       AnyNotSched = true;
287     }
288   }
289   assert(!AnyNotSched);
290 #endif
291 }
292
293 //===----------------------------------------------------------------------===//
294 //  Top-Down Scheduling
295 //===----------------------------------------------------------------------===//
296
297 /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to
298 /// the PendingQueue if the count reaches zero.
299 void ScheduleDAGRRList::ReleaseSucc(SUnit *SuccSU, bool isChain, 
300                                     unsigned CurCycle) {
301   // FIXME: the distance between two nodes is not always == the predecessor's
302   // latency. For example, the reader can very well read the register written
303   // by the predecessor later than the issue cycle. It also depends on the
304   // interrupt model (drain vs. freeze).
305   SuccSU->CycleBound = std::max(SuccSU->CycleBound, CurCycle + SuccSU->Latency);
306
307   if (!isChain)
308     SuccSU->NumPredsLeft--;
309   else
310     SuccSU->NumChainPredsLeft--;
311   
312 #ifndef NDEBUG
313   if (SuccSU->NumPredsLeft < 0 || SuccSU->NumChainPredsLeft < 0) {
314     std::cerr << "*** List scheduling failed! ***\n";
315     SuccSU->dump(&DAG);
316     std::cerr << " has been released too many times!\n";
317     assert(0);
318   }
319 #endif
320   
321   if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0) {
322     SuccSU->isAvailable = true;
323     AvailableQueue->push(SuccSU);
324   }
325 }
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 ScheduleDAGRRList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) {
332   DEBUG(std::cerr << "*** Scheduling [" << CurCycle << "]: ");
333   DEBUG(SU->dump(&DAG));
334   SU->Cycle = CurCycle;
335
336   AvailableQueue->ScheduledNode(SU);
337   Sequence.push_back(SU);
338
339   // Top down: release successors
340   for (std::set<std::pair<SUnit*, bool> >::iterator I = SU->Succs.begin(),
341          E = SU->Succs.end(); I != E; ++I)
342     ReleaseSucc(I->first, I->second, CurCycle);
343   SU->isScheduled = true;
344 }
345
346 void ScheduleDAGRRList::ListScheduleTopDown() {
347   unsigned CurCycle = 0;
348   SUnit *Entry = SUnitMap[DAG.getEntryNode().Val];
349
350   // All leaves to Available queue.
351   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
352     // It is available if it has no predecessors.
353     if (SUnits[i].Preds.size() == 0 && &SUnits[i] != Entry) {
354       AvailableQueue->push(&SUnits[i]);
355       SUnits[i].isAvailable = true;
356     }
357   }
358   
359   // Emit the entry node first.
360   ScheduleNodeTopDown(Entry, CurCycle);
361   CurCycle++;
362
363   // While Available queue is not empty, grab the node with the highest
364   // priority. If it is not ready put it back. Schedule the node.
365   std::vector<SUnit*> NotReady;
366   SUnit *CurNode = NULL;
367   while (!AvailableQueue->empty()) {
368     SUnit *CurNode = AvailableQueue->pop();
369     while (CurNode && !isReady(CurNode, CurCycle)) {
370       NotReady.push_back(CurNode);
371       CurNode = AvailableQueue->pop();
372     }
373     
374     // Add the nodes that aren't ready back onto the available list.
375     AvailableQueue->push_all(NotReady);
376     NotReady.clear();
377
378     if (CurNode != NULL)
379       ScheduleNodeTopDown(CurNode, CurCycle);
380     CurCycle++;
381   }
382   
383   
384 #ifndef NDEBUG
385   // Verify that all SUnits were scheduled.
386   bool AnyNotSched = false;
387   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
388     if (!SUnits[i].isScheduled) {
389       if (!AnyNotSched)
390         std::cerr << "*** List scheduling failed! ***\n";
391       SUnits[i].dump(&DAG);
392       std::cerr << "has not been scheduled!\n";
393       AnyNotSched = true;
394     }
395   }
396   assert(!AnyNotSched);
397 #endif
398 }
399
400
401
402 //===----------------------------------------------------------------------===//
403 //                RegReductionPriorityQueue Implementation
404 //===----------------------------------------------------------------------===//
405 //
406 // This is a SchedulingPriorityQueue that schedules using Sethi Ullman numbers
407 // to reduce register pressure.
408 // 
409 namespace {
410   template<class SF>
411   class RegReductionPriorityQueue;
412   
413   /// Sorting functions for the Available queue.
414   struct bu_ls_rr_sort : public std::binary_function<SUnit*, SUnit*, bool> {
415     RegReductionPriorityQueue<bu_ls_rr_sort> *SPQ;
416     bu_ls_rr_sort(RegReductionPriorityQueue<bu_ls_rr_sort> *spq) : SPQ(spq) {}
417     bu_ls_rr_sort(const bu_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {}
418     
419     bool operator()(const SUnit* left, const SUnit* right) const;
420   };
421
422   struct td_ls_rr_sort : public std::binary_function<SUnit*, SUnit*, bool> {
423     RegReductionPriorityQueue<td_ls_rr_sort> *SPQ;
424     td_ls_rr_sort(RegReductionPriorityQueue<td_ls_rr_sort> *spq) : SPQ(spq) {}
425     td_ls_rr_sort(const td_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {}
426     
427     bool operator()(const SUnit* left, const SUnit* right) const;
428   };
429 }  // end anonymous namespace
430
431 namespace {
432   template<class SF>
433   class RegReductionPriorityQueue : public SchedulingPriorityQueue {
434     std::priority_queue<SUnit*, std::vector<SUnit*>, SF> Queue;
435
436   public:
437     RegReductionPriorityQueue() :
438     Queue(SF(this)) {}
439     
440     virtual void initNodes(const std::vector<SUnit> &sunits) {}
441     virtual void releaseState() {}
442     
443     virtual int getSethiUllmanNumber(unsigned NodeNum) const {
444       return 0;
445     }
446     
447     bool empty() const { return Queue.empty(); }
448     
449     void push(SUnit *U) {
450       Queue.push(U);
451     }
452     void push_all(const std::vector<SUnit *> &Nodes) {
453       for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
454         Queue.push(Nodes[i]);
455     }
456     
457     SUnit *pop() {
458       if (empty()) return NULL;
459       SUnit *V = Queue.top();
460       Queue.pop();
461       return V;
462     }
463   };
464
465   template<class SF>
466   class BURegReductionPriorityQueue : public RegReductionPriorityQueue<SF> {
467     // SUnits - The SUnits for the current graph.
468     const std::vector<SUnit> *SUnits;
469     
470     // SethiUllmanNumbers - The SethiUllman number for each node.
471     std::vector<int> SethiUllmanNumbers;
472
473   public:
474     BURegReductionPriorityQueue() {}
475
476     void initNodes(const std::vector<SUnit> &sunits) {
477       SUnits = &sunits;
478       // Add pseudo dependency edges for two-address nodes.
479       AddPseudoTwoAddrDeps();
480       // Calculate node priorities.
481       CalculatePriorities();
482     }
483
484     void releaseState() {
485       SUnits = 0;
486       SethiUllmanNumbers.clear();
487     }
488
489     int getSethiUllmanNumber(unsigned NodeNum) const {
490       assert(NodeNum < SethiUllmanNumbers.size());
491       return SethiUllmanNumbers[NodeNum];
492     }
493
494   private:
495     void AddPseudoTwoAddrDeps();
496     void CalculatePriorities();
497     int CalcNodePriority(const SUnit *SU);
498   };
499
500
501   template<class SF>
502   class TDRegReductionPriorityQueue : public RegReductionPriorityQueue<SF> {
503     // SUnits - The SUnits for the current graph.
504     const std::vector<SUnit> *SUnits;
505     
506     // SethiUllmanNumbers - The SethiUllman number for each node.
507     std::vector<int> SethiUllmanNumbers;
508
509   public:
510     TDRegReductionPriorityQueue() {}
511
512     void initNodes(const std::vector<SUnit> &sunits) {
513       SUnits = &sunits;
514       // Calculate node priorities.
515       CalculatePriorities();
516     }
517
518     void releaseState() {
519       SUnits = 0;
520       SethiUllmanNumbers.clear();
521     }
522
523     int getSethiUllmanNumber(unsigned NodeNum) const {
524       assert(NodeNum < SethiUllmanNumbers.size());
525       return SethiUllmanNumbers[NodeNum];
526     }
527
528   private:
529     void CalculatePriorities();
530     int CalcNodePriority(const SUnit *SU);
531   };
532 }
533
534 static bool isFloater(const SUnit *SU) {
535   if (SU->Node->isTargetOpcode()) {
536     if (SU->NumPreds == 0)
537       return true;
538     if (SU->NumPreds == 1) {
539       for (std::set<std::pair<SUnit*, bool> >::iterator I = SU->Preds.begin(),
540              E = SU->Preds.end(); I != E; ++I) {
541         if (I->second) continue;
542
543         SUnit *PredSU = I->first;
544         unsigned Opc = PredSU->Node->getOpcode();
545         if (Opc != ISD::EntryToken && Opc != ISD::TokenFactor &&
546             Opc != ISD::CopyFromReg && Opc != ISD::CopyToReg)
547           return false;
548       }
549       return true;
550     }
551   }
552   return false;
553 }
554
555 static bool isSimpleFloaterUse(const SUnit *SU) {
556   unsigned NumOps = 0;
557   for (std::set<std::pair<SUnit*, bool> >::iterator I = SU->Preds.begin(),
558          E = SU->Preds.end(); I != E; ++I) {
559     if (I->second) continue;
560     if (++NumOps > 1)
561       return false;
562     if (!isFloater(I->first))
563       return false;
564   }
565   return true;
566 }
567
568 // Bottom up
569 bool bu_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
570   unsigned LeftNum  = left->NodeNum;
571   unsigned RightNum = right->NodeNum;
572   bool LIsTarget = left->Node->isTargetOpcode();
573   bool RIsTarget = right->Node->isTargetOpcode();
574   int LPriority = SPQ->getSethiUllmanNumber(LeftNum);
575   int RPriority = SPQ->getSethiUllmanNumber(RightNum);
576   int LBonus = 0;
577   int RBonus = 0;
578
579   // Schedule floaters (e.g. load from some constant address) and those nodes
580   // with a single predecessor each first. They maintain / reduce register
581   // pressure.
582   if (isFloater(left) || isSimpleFloaterUse(left))
583     LBonus += 2;
584   if (isFloater(right) || isSimpleFloaterUse(right))
585     RBonus += 2;
586
587   // Special tie breaker: if two nodes share a operand, the one that use it
588   // as a def&use operand is preferred.
589   if (LIsTarget && RIsTarget) {
590     if (left->isTwoAddress && !right->isTwoAddress) {
591       SDNode *DUNode = left->Node->getOperand(0).Val;
592       if (DUNode->isOperand(right->Node))
593         LBonus += 2;
594     }
595     if (!left->isTwoAddress && right->isTwoAddress) {
596       SDNode *DUNode = right->Node->getOperand(0).Val;
597       if (DUNode->isOperand(left->Node))
598         RBonus += 2;
599     }
600   }
601
602   if (LPriority+LBonus < RPriority+RBonus)
603     return true;
604   else if (LPriority+LBonus == RPriority+RBonus)
605     if (left->Height > right->Height)
606       return true;
607     else if (left->Height == right->Height)
608       if (left->Depth < right->Depth)
609         return true;
610       else if (left->Depth == right->Depth)
611         if (left->CycleBound > right->CycleBound) 
612           return true;
613   return false;
614 }
615
616 static inline bool isCopyFromLiveIn(const SUnit *SU) {
617   SDNode *N = SU->Node;
618   return N->getOpcode() == ISD::CopyFromReg &&
619     N->getOperand(N->getNumOperands()-1).getValueType() != MVT::Flag;
620 }
621
622 // FIXME: This is probably too slow!
623 static void isReachable(SUnit *SU, SUnit *TargetSU,
624                         std::set<SUnit *> &Visited, bool &Reached) {
625   if (Reached) return;
626   if (SU == TargetSU) {
627     Reached = true;
628     return;
629   }
630   if (!Visited.insert(SU).second) return;
631
632   for (std::set<std::pair<SUnit*, bool> >::iterator I = SU->Preds.begin(),
633          E = SU->Preds.end(); I != E; ++I)
634     isReachable(I->first, TargetSU, Visited, Reached);
635 }
636
637 static bool isReachable(SUnit *SU, SUnit *TargetSU) {
638   std::set<SUnit *> Visited;
639   bool Reached = false;
640   isReachable(SU, TargetSU, Visited, Reached);
641   return Reached;
642 }
643
644 static SUnit *getDefUsePredecessor(SUnit *SU) {
645   SDNode *DU = SU->Node->getOperand(0).Val;
646   for (std::set<std::pair<SUnit*, bool> >::iterator
647          I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) {
648     if (I->second) continue;  // ignore chain preds
649     SUnit *PredSU = I->first;
650     if (PredSU->Node == DU)
651       return PredSU;
652   }
653
654   // Must be flagged.
655   return NULL;
656 }
657
658 static bool canClobber(SUnit *SU, SUnit *Op) {
659   if (SU->isTwoAddress)
660     return Op == getDefUsePredecessor(SU);
661   return false;
662 }
663
664 /// AddPseudoTwoAddrDeps - If two nodes share an operand and one of them uses
665 /// it as a def&use operand. Add a pseudo control edge from it to the other
666 /// node (if it won't create a cycle) so the two-address one will be scheduled
667 /// first (lower in the schedule).
668 template<class SF>
669 void BURegReductionPriorityQueue<SF>::AddPseudoTwoAddrDeps() {
670   for (unsigned i = 0, e = SUnits->size(); i != e; ++i) {
671     SUnit *SU = (SUnit *)&((*SUnits)[i]);
672     SDNode *Node = SU->Node;
673     if (!Node->isTargetOpcode())
674       continue;
675
676     if (SU->isTwoAddress) {
677       SUnit *DUSU = getDefUsePredecessor(SU);
678       if (!DUSU) continue;
679
680       for (std::set<std::pair<SUnit*, bool> >::iterator I = DUSU->Succs.begin(),
681              E = DUSU->Succs.end(); I != E; ++I) {
682         if (I->second) continue;
683         SUnit *SuccSU = I->first;
684         if (SuccSU != SU &&
685             (!canClobber(SuccSU, DUSU) ||
686              (!SU->isCommutable && SuccSU->isCommutable))){
687           if (SuccSU->Depth == SU->Depth && !isReachable(SuccSU, SU)) {
688             DEBUG(std::cerr << "Adding an edge from SU # " << SU->NodeNum
689                   << " to SU #" << SuccSU->NodeNum << "\n");
690             if (SU->Preds.insert(std::make_pair(SuccSU, true)).second)
691               SU->NumChainPredsLeft++;
692             if (SuccSU->Succs.insert(std::make_pair(SU, true)).second)
693               SuccSU->NumChainSuccsLeft++;
694           }
695         }
696       }
697     }
698   }
699 }
700
701 /// CalcNodePriority - Priority is the Sethi Ullman number. 
702 /// Smaller number is the higher priority.
703 template<class SF>
704 int BURegReductionPriorityQueue<SF>::CalcNodePriority(const SUnit *SU) {
705   int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum];
706   if (SethiUllmanNumber != 0)
707     return SethiUllmanNumber;
708
709   unsigned Opc = SU->Node->getOpcode();
710   if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg)
711     SethiUllmanNumber = INT_MAX - 10;
712   else if (SU->NumSuccsLeft == 0)
713     // If SU does not have a use, i.e. it doesn't produce a value that would
714     // be consumed (e.g. store), then it terminates a chain of computation.
715     // Give it a small SethiUllman number so it will be scheduled right before its
716     // predecessors that it doesn't lengthen their live ranges.
717     SethiUllmanNumber = INT_MIN + 10;
718   // FIXME: remove this else if? It seems to reduce register spills but often
719   // ends up increasing runtime. Need to investigate.
720   else if (SU->NumPredsLeft == 0 &&
721            (Opc != ISD::CopyFromReg || isCopyFromLiveIn(SU)))
722     SethiUllmanNumber = INT_MAX - 10;
723   else {
724     int Extra = 0;
725     for (std::set<std::pair<SUnit*, bool> >::const_iterator
726          I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) {
727       if (I->second) continue;  // ignore chain preds
728       SUnit *PredSU = I->first;
729       int PredSethiUllman = CalcNodePriority(PredSU);
730       if (PredSethiUllman > SethiUllmanNumber) {
731         SethiUllmanNumber = PredSethiUllman;
732         Extra = 0;
733       } else if (PredSethiUllman == SethiUllmanNumber && !I->second)
734         Extra++;
735     }
736
737     SethiUllmanNumber += Extra;
738   }
739   
740   return SethiUllmanNumber;
741 }
742
743 /// CalculatePriorities - Calculate priorities of all scheduling units.
744 template<class SF>
745 void BURegReductionPriorityQueue<SF>::CalculatePriorities() {
746   SethiUllmanNumbers.assign(SUnits->size(), 0);
747   
748   for (unsigned i = 0, e = SUnits->size(); i != e; ++i)
749     CalcNodePriority(&(*SUnits)[i]);
750 }
751
752 static unsigned SumOfUnscheduledPredsOfSuccs(const SUnit *SU) {
753   unsigned Sum = 0;
754   for (std::set<std::pair<SUnit*, bool> >::const_iterator
755          I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) {
756     SUnit *SuccSU = I->first;
757     for (std::set<std::pair<SUnit*, bool> >::const_iterator
758          II = SuccSU->Preds.begin(), EE = SuccSU->Preds.end(); II != EE; ++II) {
759       SUnit *PredSU = II->first;
760       if (!PredSU->isScheduled)
761         Sum++;
762     }
763   }
764
765   return Sum;
766 }
767
768
769 // Top down
770 bool td_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
771   unsigned LeftNum  = left->NodeNum;
772   unsigned RightNum = right->NodeNum;
773   int LPriority = SPQ->getSethiUllmanNumber(LeftNum);
774   int RPriority = SPQ->getSethiUllmanNumber(RightNum);
775   bool LIsTarget = left->Node->isTargetOpcode();
776   bool RIsTarget = right->Node->isTargetOpcode();
777   bool LIsFloater = LIsTarget && left->NumPreds == 0;
778   bool RIsFloater = RIsTarget && right->NumPreds == 0;
779   unsigned LBonus = (SumOfUnscheduledPredsOfSuccs(left) == 1) ? 2 : 0;
780   unsigned RBonus = (SumOfUnscheduledPredsOfSuccs(right) == 1) ? 2 : 0;
781
782   if (left->NumSuccs == 0 && right->NumSuccs != 0)
783     return false;
784   else if (left->NumSuccs != 0 && right->NumSuccs == 0)
785     return true;
786
787   // Special tie breaker: if two nodes share a operand, the one that use it
788   // as a def&use operand is preferred.
789   if (LIsTarget && RIsTarget) {
790     if (left->isTwoAddress && !right->isTwoAddress) {
791       SDNode *DUNode = left->Node->getOperand(0).Val;
792       if (DUNode->isOperand(right->Node))
793         RBonus += 2;
794     }
795     if (!left->isTwoAddress && right->isTwoAddress) {
796       SDNode *DUNode = right->Node->getOperand(0).Val;
797       if (DUNode->isOperand(left->Node))
798         LBonus += 2;
799     }
800   }
801   if (LIsFloater)
802     LBonus -= 2;
803   if (RIsFloater)
804     RBonus -= 2;
805   if (left->NumSuccs == 1)
806     LBonus += 2;
807   if (right->NumSuccs == 1)
808     RBonus += 2;
809
810   if (LPriority+LBonus < RPriority+RBonus)
811     return true;
812   else if (LPriority == RPriority)
813     if (left->Depth < right->Depth)
814       return true;
815     else if (left->Depth == right->Depth)
816       if (left->NumSuccsLeft > right->NumSuccsLeft)
817         return true;
818       else if (left->NumSuccsLeft == right->NumSuccsLeft)
819         if (left->CycleBound > right->CycleBound) 
820           return true;
821   return false;
822 }
823
824 /// CalcNodePriority - Priority is the Sethi Ullman number. 
825 /// Smaller number is the higher priority.
826 template<class SF>
827 int TDRegReductionPriorityQueue<SF>::CalcNodePriority(const SUnit *SU) {
828   int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum];
829   if (SethiUllmanNumber != 0)
830     return SethiUllmanNumber;
831
832   unsigned Opc = SU->Node->getOpcode();
833   if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg)
834     SethiUllmanNumber = INT_MAX - 10;
835   else if (SU->NumSuccsLeft == 0)
836     // If SU does not have a use, i.e. it doesn't produce a value that would
837     // be consumed (e.g. store), then it terminates a chain of computation.
838     // Give it a small SethiUllman number so it will be scheduled right before its
839     // predecessors that it doesn't lengthen their live ranges.
840     SethiUllmanNumber = INT_MIN + 10;
841   else if (SU->NumPredsLeft == 0 &&
842            (Opc != ISD::CopyFromReg || isCopyFromLiveIn(SU)))
843     SethiUllmanNumber = 1;
844   else {
845     int Extra = 0;
846     for (std::set<std::pair<SUnit*, bool> >::const_iterator
847          I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) {
848       if (I->second) continue;  // ignore chain preds
849       SUnit *PredSU = I->first;
850       int PredSethiUllman = CalcNodePriority(PredSU);
851       if (PredSethiUllman > SethiUllmanNumber) {
852         SethiUllmanNumber = PredSethiUllman;
853         Extra = 0;
854       } else if (PredSethiUllman == SethiUllmanNumber && !I->second)
855         Extra++;
856     }
857
858     SethiUllmanNumber += Extra;
859   }
860   
861   return SethiUllmanNumber;
862 }
863
864 /// CalculatePriorities - Calculate priorities of all scheduling units.
865 template<class SF>
866 void TDRegReductionPriorityQueue<SF>::CalculatePriorities() {
867   SethiUllmanNumbers.assign(SUnits->size(), 0);
868   
869   for (unsigned i = 0, e = SUnits->size(); i != e; ++i)
870     CalcNodePriority(&(*SUnits)[i]);
871 }
872
873 //===----------------------------------------------------------------------===//
874 //                         Public Constructor Functions
875 //===----------------------------------------------------------------------===//
876
877 llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG,
878                                                     MachineBasicBlock *BB) {
879   return new ScheduleDAGRRList(DAG, BB, DAG.getTarget(), true,
880                                new BURegReductionPriorityQueue<bu_ls_rr_sort>());
881 }
882
883 llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAG &DAG,
884                                                     MachineBasicBlock *BB) {
885   return new ScheduleDAGRRList(DAG, BB, DAG.getTarget(), false,
886                                new TDRegReductionPriorityQueue<td_ls_rr_sort>());
887 }
888