3718e64d9ce7c5013f15a50738c14dd1b8f28860
[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 MRI->getRegClass(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 VISIBILITY_HIDDEN RegReductionPriorityQueue
434    : public SchedulingPriorityQueue {
435     std::priority_queue<SUnit*, std::vector<SUnit*>, SF> Queue;
436
437   public:
438     RegReductionPriorityQueue() :
439     Queue(SF(this)) {}
440     
441     virtual void initNodes(const std::vector<SUnit> &sunits) {}
442     virtual void releaseState() {}
443     
444     virtual int getSethiUllmanNumber(unsigned NodeNum) const {
445       return 0;
446     }
447     
448     bool empty() const { return Queue.empty(); }
449     
450     void push(SUnit *U) {
451       Queue.push(U);
452     }
453     void push_all(const std::vector<SUnit *> &Nodes) {
454       for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
455         Queue.push(Nodes[i]);
456     }
457     
458     SUnit *pop() {
459       if (empty()) return NULL;
460       SUnit *V = Queue.top();
461       Queue.pop();
462       return V;
463     }
464   };
465
466   template<class SF>
467   class VISIBILITY_HIDDEN BURegReductionPriorityQueue
468    : public RegReductionPriorityQueue<SF> {
469     // SUnits - The SUnits for the current graph.
470     const std::vector<SUnit> *SUnits;
471     
472     // SethiUllmanNumbers - The SethiUllman number for each node.
473     std::vector<int> SethiUllmanNumbers;
474
475   public:
476     BURegReductionPriorityQueue() {}
477
478     void initNodes(const std::vector<SUnit> &sunits) {
479       SUnits = &sunits;
480       // Add pseudo dependency edges for two-address nodes.
481       AddPseudoTwoAddrDeps();
482       // Calculate node priorities.
483       CalculatePriorities();
484     }
485
486     void releaseState() {
487       SUnits = 0;
488       SethiUllmanNumbers.clear();
489     }
490
491     int getSethiUllmanNumber(unsigned NodeNum) const {
492       assert(NodeNum < SethiUllmanNumbers.size());
493       return SethiUllmanNumbers[NodeNum];
494     }
495
496   private:
497     void AddPseudoTwoAddrDeps();
498     void CalculatePriorities();
499     int CalcNodePriority(const SUnit *SU);
500   };
501
502
503   template<class SF>
504   class TDRegReductionPriorityQueue : public RegReductionPriorityQueue<SF> {
505     // SUnits - The SUnits for the current graph.
506     const std::vector<SUnit> *SUnits;
507     
508     // SethiUllmanNumbers - The SethiUllman number for each node.
509     std::vector<int> SethiUllmanNumbers;
510
511   public:
512     TDRegReductionPriorityQueue() {}
513
514     void initNodes(const std::vector<SUnit> &sunits) {
515       SUnits = &sunits;
516       // Calculate node priorities.
517       CalculatePriorities();
518     }
519
520     void releaseState() {
521       SUnits = 0;
522       SethiUllmanNumbers.clear();
523     }
524
525     int getSethiUllmanNumber(unsigned NodeNum) const {
526       assert(NodeNum < SethiUllmanNumbers.size());
527       return SethiUllmanNumbers[NodeNum];
528     }
529
530   private:
531     void CalculatePriorities();
532     int CalcNodePriority(const SUnit *SU);
533   };
534 }
535
536 static bool isFloater(const SUnit *SU) {
537   if (SU->Node->isTargetOpcode()) {
538     if (SU->NumPreds == 0)
539       return true;
540     if (SU->NumPreds == 1) {
541       for (std::set<std::pair<SUnit*, bool> >::iterator I = SU->Preds.begin(),
542              E = SU->Preds.end(); I != E; ++I) {
543         if (I->second) continue;
544
545         SUnit *PredSU = I->first;
546         unsigned Opc = PredSU->Node->getOpcode();
547         if (Opc != ISD::EntryToken && Opc != ISD::TokenFactor &&
548             Opc != ISD::CopyFromReg && Opc != ISD::CopyToReg)
549           return false;
550       }
551       return true;
552     }
553   }
554   return false;
555 }
556
557 static bool isSimpleFloaterUse(const SUnit *SU) {
558   unsigned NumOps = 0;
559   for (std::set<std::pair<SUnit*, bool> >::iterator I = SU->Preds.begin(),
560          E = SU->Preds.end(); I != E; ++I) {
561     if (I->second) continue;
562     if (++NumOps > 1)
563       return false;
564     if (!isFloater(I->first))
565       return false;
566   }
567   return true;
568 }
569
570 // Bottom up
571 bool bu_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
572   unsigned LeftNum  = left->NodeNum;
573   unsigned RightNum = right->NodeNum;
574   bool LIsTarget = left->Node->isTargetOpcode();
575   bool RIsTarget = right->Node->isTargetOpcode();
576   int LPriority = SPQ->getSethiUllmanNumber(LeftNum);
577   int RPriority = SPQ->getSethiUllmanNumber(RightNum);
578   int LBonus = 0;
579   int RBonus = 0;
580
581   // Schedule floaters (e.g. load from some constant address) and those nodes
582   // with a single predecessor each first. They maintain / reduce register
583   // pressure.
584   if (isFloater(left) || isSimpleFloaterUse(left))
585     LBonus += 2;
586   if (isFloater(right) || isSimpleFloaterUse(right))
587     RBonus += 2;
588
589   // Special tie breaker: if two nodes share a operand, the one that use it
590   // as a def&use operand is preferred.
591   if (LIsTarget && RIsTarget) {
592     if (left->isTwoAddress && !right->isTwoAddress) {
593       SDNode *DUNode = left->Node->getOperand(0).Val;
594       if (DUNode->isOperand(right->Node))
595         LBonus += 2;
596     }
597     if (!left->isTwoAddress && right->isTwoAddress) {
598       SDNode *DUNode = right->Node->getOperand(0).Val;
599       if (DUNode->isOperand(left->Node))
600         RBonus += 2;
601     }
602   }
603
604   if (LPriority+LBonus < RPriority+RBonus)
605     return true;
606   else if (LPriority+LBonus == RPriority+RBonus)
607     if (left->Height > right->Height)
608       return true;
609     else if (left->Height == right->Height)
610       if (left->Depth < right->Depth)
611         return true;
612       else if (left->Depth == right->Depth)
613         if (left->CycleBound > right->CycleBound) 
614           return true;
615   return false;
616 }
617
618 static inline bool isCopyFromLiveIn(const SUnit *SU) {
619   SDNode *N = SU->Node;
620   return N->getOpcode() == ISD::CopyFromReg &&
621     N->getOperand(N->getNumOperands()-1).getValueType() != MVT::Flag;
622 }
623
624 // FIXME: This is probably too slow!
625 static void isReachable(SUnit *SU, SUnit *TargetSU,
626                         std::set<SUnit *> &Visited, bool &Reached) {
627   if (Reached) return;
628   if (SU == TargetSU) {
629     Reached = true;
630     return;
631   }
632   if (!Visited.insert(SU).second) return;
633
634   for (std::set<std::pair<SUnit*, bool> >::iterator I = SU->Preds.begin(),
635          E = SU->Preds.end(); I != E; ++I)
636     isReachable(I->first, TargetSU, Visited, Reached);
637 }
638
639 static bool isReachable(SUnit *SU, SUnit *TargetSU) {
640   std::set<SUnit *> Visited;
641   bool Reached = false;
642   isReachable(SU, TargetSU, Visited, Reached);
643   return Reached;
644 }
645
646 static SUnit *getDefUsePredecessor(SUnit *SU) {
647   SDNode *DU = SU->Node->getOperand(0).Val;
648   for (std::set<std::pair<SUnit*, bool> >::iterator
649          I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) {
650     if (I->second) continue;  // ignore chain preds
651     SUnit *PredSU = I->first;
652     if (PredSU->Node == DU)
653       return PredSU;
654   }
655
656   // Must be flagged.
657   return NULL;
658 }
659
660 static bool canClobber(SUnit *SU, SUnit *Op) {
661   if (SU->isTwoAddress)
662     return Op == getDefUsePredecessor(SU);
663   return false;
664 }
665
666 /// AddPseudoTwoAddrDeps - If two nodes share an operand and one of them uses
667 /// it as a def&use operand. Add a pseudo control edge from it to the other
668 /// node (if it won't create a cycle) so the two-address one will be scheduled
669 /// first (lower in the schedule).
670 template<class SF>
671 void BURegReductionPriorityQueue<SF>::AddPseudoTwoAddrDeps() {
672   for (unsigned i = 0, e = SUnits->size(); i != e; ++i) {
673     SUnit *SU = (SUnit *)&((*SUnits)[i]);
674     SDNode *Node = SU->Node;
675     if (!Node->isTargetOpcode())
676       continue;
677
678     if (SU->isTwoAddress) {
679       SUnit *DUSU = getDefUsePredecessor(SU);
680       if (!DUSU) continue;
681
682       for (std::set<std::pair<SUnit*, bool> >::iterator I = DUSU->Succs.begin(),
683              E = DUSU->Succs.end(); I != E; ++I) {
684         if (I->second) continue;
685         SUnit *SuccSU = I->first;
686         if (SuccSU != SU &&
687             (!canClobber(SuccSU, DUSU) ||
688              (!SU->isCommutable && SuccSU->isCommutable))){
689           if (SuccSU->Depth == SU->Depth && !isReachable(SuccSU, SU)) {
690             DEBUG(std::cerr << "Adding an edge from SU # " << SU->NodeNum
691                   << " to SU #" << SuccSU->NodeNum << "\n");
692             if (SU->Preds.insert(std::make_pair(SuccSU, true)).second)
693               SU->NumChainPredsLeft++;
694             if (SuccSU->Succs.insert(std::make_pair(SU, true)).second)
695               SuccSU->NumChainSuccsLeft++;
696           }
697         }
698       }
699     }
700   }
701 }
702
703 /// CalcNodePriority - Priority is the Sethi Ullman number. 
704 /// Smaller number is the higher priority.
705 template<class SF>
706 int BURegReductionPriorityQueue<SF>::CalcNodePriority(const SUnit *SU) {
707   int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum];
708   if (SethiUllmanNumber != 0)
709     return SethiUllmanNumber;
710
711   unsigned Opc = SU->Node->getOpcode();
712   if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg)
713     SethiUllmanNumber = INT_MAX - 10;
714   else if (SU->NumSuccsLeft == 0)
715     // If SU does not have a use, i.e. it doesn't produce a value that would
716     // be consumed (e.g. store), then it terminates a chain of computation.
717     // Give it a small SethiUllman number so it will be scheduled right before its
718     // predecessors that it doesn't lengthen their live ranges.
719     SethiUllmanNumber = INT_MIN + 10;
720   // FIXME: remove this else if? It seems to reduce register spills but often
721   // ends up increasing runtime. Need to investigate.
722   else if (SU->NumPredsLeft == 0 &&
723            (Opc != ISD::CopyFromReg || isCopyFromLiveIn(SU)))
724     SethiUllmanNumber = INT_MAX - 10;
725   else {
726     int Extra = 0;
727     for (std::set<std::pair<SUnit*, bool> >::const_iterator
728          I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) {
729       if (I->second) continue;  // ignore chain preds
730       SUnit *PredSU = I->first;
731       int PredSethiUllman = CalcNodePriority(PredSU);
732       if (PredSethiUllman > SethiUllmanNumber) {
733         SethiUllmanNumber = PredSethiUllman;
734         Extra = 0;
735       } else if (PredSethiUllman == SethiUllmanNumber && !I->second)
736         Extra++;
737     }
738
739     SethiUllmanNumber += Extra;
740   }
741   
742   return SethiUllmanNumber;
743 }
744
745 /// CalculatePriorities - Calculate priorities of all scheduling units.
746 template<class SF>
747 void BURegReductionPriorityQueue<SF>::CalculatePriorities() {
748   SethiUllmanNumbers.assign(SUnits->size(), 0);
749   
750   for (unsigned i = 0, e = SUnits->size(); i != e; ++i)
751     CalcNodePriority(&(*SUnits)[i]);
752 }
753
754 static unsigned SumOfUnscheduledPredsOfSuccs(const SUnit *SU) {
755   unsigned Sum = 0;
756   for (std::set<std::pair<SUnit*, bool> >::const_iterator
757          I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) {
758     SUnit *SuccSU = I->first;
759     for (std::set<std::pair<SUnit*, bool> >::const_iterator
760          II = SuccSU->Preds.begin(), EE = SuccSU->Preds.end(); II != EE; ++II) {
761       SUnit *PredSU = II->first;
762       if (!PredSU->isScheduled)
763         Sum++;
764     }
765   }
766
767   return Sum;
768 }
769
770
771 // Top down
772 bool td_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
773   unsigned LeftNum  = left->NodeNum;
774   unsigned RightNum = right->NodeNum;
775   int LPriority = SPQ->getSethiUllmanNumber(LeftNum);
776   int RPriority = SPQ->getSethiUllmanNumber(RightNum);
777   bool LIsTarget = left->Node->isTargetOpcode();
778   bool RIsTarget = right->Node->isTargetOpcode();
779   bool LIsFloater = LIsTarget && left->NumPreds == 0;
780   bool RIsFloater = RIsTarget && right->NumPreds == 0;
781   unsigned LBonus = (SumOfUnscheduledPredsOfSuccs(left) == 1) ? 2 : 0;
782   unsigned RBonus = (SumOfUnscheduledPredsOfSuccs(right) == 1) ? 2 : 0;
783
784   if (left->NumSuccs == 0 && right->NumSuccs != 0)
785     return false;
786   else if (left->NumSuccs != 0 && right->NumSuccs == 0)
787     return true;
788
789   // Special tie breaker: if two nodes share a operand, the one that use it
790   // as a def&use operand is preferred.
791   if (LIsTarget && RIsTarget) {
792     if (left->isTwoAddress && !right->isTwoAddress) {
793       SDNode *DUNode = left->Node->getOperand(0).Val;
794       if (DUNode->isOperand(right->Node))
795         RBonus += 2;
796     }
797     if (!left->isTwoAddress && right->isTwoAddress) {
798       SDNode *DUNode = right->Node->getOperand(0).Val;
799       if (DUNode->isOperand(left->Node))
800         LBonus += 2;
801     }
802   }
803   if (LIsFloater)
804     LBonus -= 2;
805   if (RIsFloater)
806     RBonus -= 2;
807   if (left->NumSuccs == 1)
808     LBonus += 2;
809   if (right->NumSuccs == 1)
810     RBonus += 2;
811
812   if (LPriority+LBonus < RPriority+RBonus)
813     return true;
814   else if (LPriority == RPriority)
815     if (left->Depth < right->Depth)
816       return true;
817     else if (left->Depth == right->Depth)
818       if (left->NumSuccsLeft > right->NumSuccsLeft)
819         return true;
820       else if (left->NumSuccsLeft == right->NumSuccsLeft)
821         if (left->CycleBound > right->CycleBound) 
822           return true;
823   return false;
824 }
825
826 /// CalcNodePriority - Priority is the Sethi Ullman number. 
827 /// Smaller number is the higher priority.
828 template<class SF>
829 int TDRegReductionPriorityQueue<SF>::CalcNodePriority(const SUnit *SU) {
830   int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum];
831   if (SethiUllmanNumber != 0)
832     return SethiUllmanNumber;
833
834   unsigned Opc = SU->Node->getOpcode();
835   if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg)
836     SethiUllmanNumber = INT_MAX - 10;
837   else if (SU->NumSuccsLeft == 0)
838     // If SU does not have a use, i.e. it doesn't produce a value that would
839     // be consumed (e.g. store), then it terminates a chain of computation.
840     // Give it a small SethiUllman number so it will be scheduled right before its
841     // predecessors that it doesn't lengthen their live ranges.
842     SethiUllmanNumber = INT_MIN + 10;
843   else if (SU->NumPredsLeft == 0 &&
844            (Opc != ISD::CopyFromReg || isCopyFromLiveIn(SU)))
845     SethiUllmanNumber = 1;
846   else {
847     int Extra = 0;
848     for (std::set<std::pair<SUnit*, bool> >::const_iterator
849          I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) {
850       if (I->second) continue;  // ignore chain preds
851       SUnit *PredSU = I->first;
852       int PredSethiUllman = CalcNodePriority(PredSU);
853       if (PredSethiUllman > SethiUllmanNumber) {
854         SethiUllmanNumber = PredSethiUllman;
855         Extra = 0;
856       } else if (PredSethiUllman == SethiUllmanNumber && !I->second)
857         Extra++;
858     }
859
860     SethiUllmanNumber += Extra;
861   }
862   
863   return SethiUllmanNumber;
864 }
865
866 /// CalculatePriorities - Calculate priorities of all scheduling units.
867 template<class SF>
868 void TDRegReductionPriorityQueue<SF>::CalculatePriorities() {
869   SethiUllmanNumbers.assign(SUnits->size(), 0);
870   
871   for (unsigned i = 0, e = SUnits->size(); i != e; ++i)
872     CalcNodePriority(&(*SUnits)[i]);
873 }
874
875 //===----------------------------------------------------------------------===//
876 //                         Public Constructor Functions
877 //===----------------------------------------------------------------------===//
878
879 llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG,
880                                                     MachineBasicBlock *BB) {
881   return new ScheduleDAGRRList(DAG, BB, DAG.getTarget(), true,
882                                new BURegReductionPriorityQueue<bu_ls_rr_sort>());
883 }
884
885 llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAG &DAG,
886                                                     MachineBasicBlock *BB) {
887   return new ScheduleDAGRRList(DAG, BB, DAG.getTarget(), false,
888                                new TDRegReductionPriorityQueue<td_ls_rr_sort>());
889 }
890