Use archive libraries instead of object files for VMCore, BCReader,
[oota-llvm.git] / lib / CodeGen / SelectionDAG / ScheduleDAGSimple.cpp
1 //===-- ScheduleDAGSimple.cpp - Implement a trivial DAG scheduler ---------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by James M. Laskey and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This implements a simple two pass scheduler.  The first pass attempts to push
11 // backward any lengthy instructions and critical paths.  The second pass packs
12 // instructions into semi-optimal time slots.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #define DEBUG_TYPE "sched"
17 #include "llvm/CodeGen/ScheduleDAG.h"
18 #include "llvm/CodeGen/SelectionDAG.h"
19 #include "llvm/Target/TargetData.h"
20 #include "llvm/Target/TargetMachine.h"
21 #include "llvm/Target/TargetInstrInfo.h"
22 #include "llvm/Support/Debug.h"
23 #include <algorithm>
24 #include <iostream>
25 using namespace llvm;
26
27 namespace {
28 class NodeInfo;
29 typedef NodeInfo *NodeInfoPtr;
30 typedef std::vector<NodeInfoPtr>           NIVector;
31 typedef std::vector<NodeInfoPtr>::iterator NIIterator;
32
33 //===--------------------------------------------------------------------===//
34 ///
35 /// Node group -  This struct is used to manage flagged node groups.
36 ///
37 class NodeGroup {
38 public:
39   NodeGroup     *Next;
40 private:
41   NIVector      Members;                // Group member nodes
42   NodeInfo      *Dominator;             // Node with highest latency
43   unsigned      Latency;                // Total latency of the group
44   int           Pending;                // Number of visits pending before
45                                         // adding to order  
46
47 public:
48   // Ctor.
49   NodeGroup() : Next(NULL), Dominator(NULL), Pending(0) {}
50
51   // Accessors
52   inline void setDominator(NodeInfo *D) { Dominator = D; }
53   inline NodeInfo *getTop() { return Members.front(); }
54   inline NodeInfo *getBottom() { return Members.back(); }
55   inline NodeInfo *getDominator() { return Dominator; }
56   inline void setLatency(unsigned L) { Latency = L; }
57   inline unsigned getLatency() { return Latency; }
58   inline int getPending() const { return Pending; }
59   inline void setPending(int P)  { Pending = P; }
60   inline int addPending(int I)  { return Pending += I; }
61
62   // Pass thru
63   inline bool group_empty() { return Members.empty(); }
64   inline NIIterator group_begin() { return Members.begin(); }
65   inline NIIterator group_end() { return Members.end(); }
66   inline void group_push_back(const NodeInfoPtr &NI) {
67     Members.push_back(NI);
68   }
69   inline NIIterator group_insert(NIIterator Pos, const NodeInfoPtr &NI) {
70     return Members.insert(Pos, NI);
71   }
72   inline void group_insert(NIIterator Pos, NIIterator First,
73                            NIIterator Last) {
74     Members.insert(Pos, First, Last);
75   }
76
77   static void Add(NodeInfo *D, NodeInfo *U);
78 };
79
80 //===--------------------------------------------------------------------===//
81 ///
82 /// NodeInfo - This struct tracks information used to schedule the a node.
83 ///
84 class NodeInfo {
85 private:
86   int           Pending;                // Number of visits pending before
87                                         // adding to order
88 public:
89   SDNode        *Node;                  // DAG node
90   InstrStage    *StageBegin;            // First stage in itinerary
91   InstrStage    *StageEnd;              // Last+1 stage in itinerary
92   unsigned      Latency;                // Total cycles to complete instr
93   bool          IsCall : 1;             // Is function call
94   bool          IsLoad : 1;             // Is memory load
95   bool          IsStore : 1;            // Is memory store
96   unsigned      Slot;                   // Node's time slot
97   NodeGroup     *Group;                 // Grouping information
98 #ifndef NDEBUG
99   unsigned      Preorder;               // Index before scheduling
100 #endif
101
102   // Ctor.
103   NodeInfo(SDNode *N = NULL)
104     : Pending(0)
105     , Node(N)
106     , StageBegin(NULL)
107     , StageEnd(NULL)
108     , Latency(0)
109     , IsCall(false)
110     , Slot(0)
111     , Group(NULL)
112 #ifndef NDEBUG
113     , Preorder(0)
114 #endif
115   {}
116
117   // Accessors
118   inline bool isInGroup() const {
119     assert(!Group || !Group->group_empty() && "Group with no members");
120     return Group != NULL;
121   }
122   inline bool isGroupDominator() const {
123     return isInGroup() && Group->getDominator() == this;
124   }
125   inline int getPending() const {
126     return Group ? Group->getPending() : Pending;
127   }
128   inline void setPending(int P) {
129     if (Group) Group->setPending(P);
130     else       Pending = P;
131   }
132   inline int addPending(int I) {
133     if (Group) return Group->addPending(I);
134     else       return Pending += I;
135   }
136 };
137
138 //===--------------------------------------------------------------------===//
139 ///
140 /// NodeGroupIterator - Iterates over all the nodes indicated by the node
141 /// info. If the node is in a group then iterate over the members of the
142 /// group, otherwise just the node info.
143 ///
144 class NodeGroupIterator {
145 private:
146   NodeInfo   *NI;                       // Node info
147   NIIterator NGI;                       // Node group iterator
148   NIIterator NGE;                       // Node group iterator end
149
150 public:
151   // Ctor.
152   NodeGroupIterator(NodeInfo *N) : NI(N) {
153     // If the node is in a group then set up the group iterator.  Otherwise
154     // the group iterators will trip first time out.
155     if (N->isInGroup()) {
156       // get Group
157       NodeGroup *Group = NI->Group;
158       NGI = Group->group_begin();
159       NGE = Group->group_end();
160       // Prevent this node from being used (will be in members list
161       NI = NULL;
162     }
163   }
164
165   /// next - Return the next node info, otherwise NULL.
166   ///
167   NodeInfo *next() {
168     // If members list
169     if (NGI != NGE) return *NGI++;
170     // Use node as the result (may be NULL)
171     NodeInfo *Result = NI;
172     // Only use once
173     NI = NULL;
174     // Return node or NULL
175     return Result;
176   }
177 };
178 //===--------------------------------------------------------------------===//
179
180
181 //===--------------------------------------------------------------------===//
182 ///
183 /// NodeGroupOpIterator - Iterates over all the operands of a node.  If the
184 /// node is a member of a group, this iterates over all the operands of all
185 /// the members of the group.
186 ///
187 class NodeGroupOpIterator {
188 private:
189   NodeInfo            *NI;              // Node containing operands
190   NodeGroupIterator   GI;               // Node group iterator
191   SDNode::op_iterator OI;               // Operand iterator
192   SDNode::op_iterator OE;               // Operand iterator end
193
194   /// CheckNode - Test if node has more operands.  If not get the next node
195   /// skipping over nodes that have no operands.
196   void CheckNode() {
197     // Only if operands are exhausted first
198     while (OI == OE) {
199       // Get next node info
200       NodeInfo *NI = GI.next();
201       // Exit if nodes are exhausted
202       if (!NI) return;
203       // Get node itself
204       SDNode *Node = NI->Node;
205       // Set up the operand iterators
206       OI = Node->op_begin();
207       OE = Node->op_end();
208     }
209   }
210
211 public:
212   // Ctor.
213   NodeGroupOpIterator(NodeInfo *N)
214     : NI(N), GI(N), OI(SDNode::op_iterator()), OE(SDNode::op_iterator()) {}
215
216   /// isEnd - Returns true when not more operands are available.
217   ///
218   inline bool isEnd() { CheckNode(); return OI == OE; }
219
220   /// next - Returns the next available operand.
221   ///
222   inline SDOperand next() {
223     assert(OI != OE &&
224            "Not checking for end of NodeGroupOpIterator correctly");
225     return *OI++;
226   }
227 };
228
229
230 //===----------------------------------------------------------------------===//
231 ///
232 /// BitsIterator - Provides iteration through individual bits in a bit vector.
233 ///
234 template<class T>
235 class BitsIterator {
236 private:
237   T Bits;                               // Bits left to iterate through
238
239 public:
240   /// Ctor.
241   BitsIterator(T Initial) : Bits(Initial) {}
242   
243   /// Next - Returns the next bit set or zero if exhausted.
244   inline T Next() {
245     // Get the rightmost bit set
246     T Result = Bits & -Bits;
247     // Remove from rest
248     Bits &= ~Result;
249     // Return single bit or zero
250     return Result;
251   }
252 };
253   
254 //===----------------------------------------------------------------------===//
255
256
257 //===----------------------------------------------------------------------===//
258 ///
259 /// ResourceTally - Manages the use of resources over time intervals.  Each
260 /// item (slot) in the tally vector represents the resources used at a given
261 /// moment.  A bit set to 1 indicates that a resource is in use, otherwise
262 /// available.  An assumption is made that the tally is large enough to schedule 
263 /// all current instructions (asserts otherwise.)
264 ///
265 template<class T>
266 class ResourceTally {
267 private:
268   std::vector<T> Tally;                 // Resources used per slot
269   typedef typename std::vector<T>::iterator Iter;
270                                         // Tally iterator 
271   
272   /// SlotsAvailable - Returns true if all units are available.
273         ///
274   bool SlotsAvailable(Iter Begin, unsigned N, unsigned ResourceSet,
275                                               unsigned &Resource) {
276     assert(N && "Must check availability with N != 0");
277     // Determine end of interval
278     Iter End = Begin + N;
279     assert(End <= Tally.end() && "Tally is not large enough for schedule");
280     
281     // Iterate thru each resource
282     BitsIterator<T> Resources(ResourceSet & ~*Begin);
283     while (unsigned Res = Resources.Next()) {
284       // Check if resource is available for next N slots
285       Iter Interval = End;
286       do {
287         Interval--;
288         if (*Interval & Res) break;
289       } while (Interval != Begin);
290       
291       // If available for N
292       if (Interval == Begin) {
293         // Success
294         Resource = Res;
295         return true;
296       }
297     }
298     
299     // No luck
300     Resource = 0;
301     return false;
302   }
303         
304         /// RetrySlot - Finds a good candidate slot to retry search.
305   Iter RetrySlot(Iter Begin, unsigned N, unsigned ResourceSet) {
306     assert(N && "Must check availability with N != 0");
307     // Determine end of interval
308     Iter End = Begin + N;
309     assert(End <= Tally.end() && "Tally is not large enough for schedule");
310                 
311                 while (Begin != End--) {
312                         // Clear units in use
313                         ResourceSet &= ~*End;
314                         // If no units left then we should go no further 
315                         if (!ResourceSet) return End + 1;
316                 }
317                 // Made it all the way through
318                 return Begin;
319         }
320   
321   /// FindAndReserveStages - Return true if the stages can be completed. If
322   /// so mark as busy.
323   bool FindAndReserveStages(Iter Begin,
324                             InstrStage *Stage, InstrStage *StageEnd) {
325     // If at last stage then we're done
326     if (Stage == StageEnd) return true;
327     // Get number of cycles for current stage
328     unsigned N = Stage->Cycles;
329     // Check to see if N slots are available, if not fail
330     unsigned Resource;
331     if (!SlotsAvailable(Begin, N, Stage->Units, Resource)) return false;
332     // Check to see if remaining stages are available, if not fail
333     if (!FindAndReserveStages(Begin + N, Stage + 1, StageEnd)) return false;
334     // Reserve resource
335     Reserve(Begin, N, Resource);
336     // Success
337     return true;
338   }
339
340   /// Reserve - Mark busy (set) the specified N slots.
341   void Reserve(Iter Begin, unsigned N, unsigned Resource) {
342     // Determine end of interval
343     Iter End = Begin + N;
344     assert(End <= Tally.end() && "Tally is not large enough for schedule");
345  
346     // Set resource bit in each slot
347     for (; Begin < End; Begin++)
348       *Begin |= Resource;
349   }
350
351   /// FindSlots - Starting from Begin, locate consecutive slots where all stages
352   /// can be completed.  Returns the address of first slot.
353   Iter FindSlots(Iter Begin, InstrStage *StageBegin, InstrStage *StageEnd) {
354     // Track position      
355     Iter Cursor = Begin;
356     
357     // Try all possible slots forward
358     while (true) {
359       // Try at cursor, if successful return position.
360       if (FindAndReserveStages(Cursor, StageBegin, StageEnd)) return Cursor;
361       // Locate a better position
362                         Cursor = RetrySlot(Cursor + 1, StageBegin->Cycles, StageBegin->Units);
363     }
364   }
365   
366 public:
367   /// Initialize - Resize and zero the tally to the specified number of time
368   /// slots.
369   inline void Initialize(unsigned N) {
370     Tally.assign(N, 0);   // Initialize tally to all zeros.
371   }
372
373   // FindAndReserve - Locate an ideal slot for the specified stages and mark
374   // as busy.
375   unsigned FindAndReserve(unsigned Slot, InstrStage *StageBegin,
376                                          InstrStage *StageEnd) {
377                 // Where to begin 
378                 Iter Begin = Tally.begin() + Slot;
379                 // Find a free slot
380                 Iter Where = FindSlots(Begin, StageBegin, StageEnd);
381                 // Distance is slot number
382                 unsigned Final = Where - Tally.begin();
383     return Final;
384   }
385
386 };
387
388 //===----------------------------------------------------------------------===//
389 ///
390 /// ScheduleDAGSimple - Simple two pass scheduler.
391 ///
392 class ScheduleDAGSimple : public ScheduleDAG {
393 private:
394   bool NoSched;                         // Just do a BFS schedule, nothing fancy
395   bool NoItins;                         // Don't use itineraries?
396   ResourceTally<unsigned> Tally;        // Resource usage tally
397   unsigned NSlots;                      // Total latency
398   static const unsigned NotFound = ~0U; // Search marker
399
400   unsigned NodeCount;                   // Number of nodes in DAG
401   std::map<SDNode *, NodeInfo *> Map;   // Map nodes to info
402   bool HasGroups;                       // True if there are any groups
403   NodeInfo *Info;                       // Info for nodes being scheduled
404   NIVector Ordering;                    // Emit ordering of nodes
405   NodeGroup *HeadNG, *TailNG;           // Keep track of allocated NodeGroups
406   
407 public:
408
409   // Ctor.
410   ScheduleDAGSimple(bool noSched, bool noItins, SelectionDAG &dag,
411                     MachineBasicBlock *bb, const TargetMachine &tm)
412     : ScheduleDAG(dag, bb, tm), NoSched(noSched), NoItins(noItins), NSlots(0),
413     NodeCount(0), HasGroups(false), Info(NULL), HeadNG(NULL), TailNG(NULL) {
414     assert(&TII && "Target doesn't provide instr info?");
415     assert(&MRI && "Target doesn't provide register info?");
416   }
417
418   virtual ~ScheduleDAGSimple() {
419     if (Info)
420       delete[] Info;
421     
422     NodeGroup *NG = HeadNG;
423     while (NG) {
424       NodeGroup *NextSU = NG->Next;
425       delete NG;
426       NG = NextSU;
427     }
428   }
429
430   void Schedule();
431
432   /// getNI - Returns the node info for the specified node.
433   ///
434   NodeInfo *getNI(SDNode *Node) { return Map[Node]; }
435   
436 private:
437   static bool isDefiner(NodeInfo *A, NodeInfo *B);
438   void IncludeNode(NodeInfo *NI);
439   void VisitAll();
440   void GatherSchedulingInfo();
441   void FakeGroupDominators(); 
442   bool isStrongDependency(NodeInfo *A, NodeInfo *B);
443   bool isWeakDependency(NodeInfo *A, NodeInfo *B);
444   void ScheduleBackward();
445   void ScheduleForward();
446   
447   void AddToGroup(NodeInfo *D, NodeInfo *U);
448   /// PrepareNodeInfo - Set up the basic minimum node info for scheduling.
449   /// 
450   void PrepareNodeInfo();
451   
452   /// IdentifyGroups - Put flagged nodes into groups.
453   ///
454   void IdentifyGroups();
455   
456   /// print - Print ordering to specified output stream.
457   ///
458   void print(std::ostream &O) const;
459   
460   void dump(const char *tag) const;
461   
462   virtual void dump() const;
463   
464   /// EmitAll - Emit all nodes in schedule sorted order.
465   ///
466   void EmitAll();
467
468   /// printNI - Print node info.
469   ///
470   void printNI(std::ostream &O, NodeInfo *NI) const;
471   
472   /// printChanges - Hilight changes in order caused by scheduling.
473   ///
474   void printChanges(unsigned Index) const;
475 };
476
477 //===----------------------------------------------------------------------===//
478 /// Special case itineraries.
479 ///
480 enum {
481   CallLatency = 40,          // To push calls back in time
482
483   RSInteger   = 0xC0000000,  // Two integer units
484   RSFloat     = 0x30000000,  // Two float units
485   RSLoadStore = 0x0C000000,  // Two load store units
486   RSBranch    = 0x02000000   // One branch unit
487 };
488 static InstrStage CallStage  = { CallLatency, RSBranch };
489 static InstrStage LoadStage  = { 5, RSLoadStore };
490 static InstrStage StoreStage = { 2, RSLoadStore };
491 static InstrStage IntStage   = { 2, RSInteger };
492 static InstrStage FloatStage = { 3, RSFloat };
493 //===----------------------------------------------------------------------===//
494
495 } // namespace
496
497 //===----------------------------------------------------------------------===//
498
499 /// PrepareNodeInfo - Set up the basic minimum node info for scheduling.
500 /// 
501 void ScheduleDAGSimple::PrepareNodeInfo() {
502   // Allocate node information
503   Info = new NodeInfo[NodeCount];
504   
505   unsigned i = 0;
506   for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
507        E = DAG.allnodes_end(); I != E; ++I, ++i) {
508     // Fast reference to node schedule info
509     NodeInfo* NI = &Info[i];
510     // Set up map
511     Map[I] = NI;
512     // Set node
513     NI->Node = I;
514     // Set pending visit count
515     NI->setPending(I->use_size());
516   }
517 }
518
519 /// IdentifyGroups - Put flagged nodes into groups.
520 ///
521 void ScheduleDAGSimple::IdentifyGroups() {
522   for (unsigned i = 0, N = NodeCount; i < N; i++) {
523     NodeInfo* NI = &Info[i];
524     SDNode *Node = NI->Node;
525     
526     // For each operand (in reverse to only look at flags)
527     for (unsigned N = Node->getNumOperands(); 0 < N--;) {
528       // Get operand
529       SDOperand Op = Node->getOperand(N);
530       // No more flags to walk
531       if (Op.getValueType() != MVT::Flag) break;
532       // Add to node group
533       AddToGroup(getNI(Op.Val), NI);
534       // Let everyone else know
535       HasGroups = true;
536     }
537   }
538 }
539
540 /// CountInternalUses - Returns the number of edges between the two nodes.
541 ///
542 static unsigned CountInternalUses(NodeInfo *D, NodeInfo *U) {
543   unsigned N = 0;
544   for (unsigned M = U->Node->getNumOperands(); 0 < M--;) {
545     SDOperand Op = U->Node->getOperand(M);
546     if (Op.Val == D->Node) N++;
547   }
548   
549   return N;
550 }
551
552 //===----------------------------------------------------------------------===//
553 /// Add - Adds a definer and user pair to a node group.
554 ///
555 void ScheduleDAGSimple::AddToGroup(NodeInfo *D, NodeInfo *U) {
556   // Get current groups
557   NodeGroup *DGroup = D->Group;
558   NodeGroup *UGroup = U->Group;
559   // If both are members of groups
560   if (DGroup && UGroup) {
561     // There may have been another edge connecting 
562     if (DGroup == UGroup) return;
563     // Add the pending users count
564     DGroup->addPending(UGroup->getPending());
565     // For each member of the users group
566     NodeGroupIterator UNGI(U);
567     while (NodeInfo *UNI = UNGI.next() ) {
568       // Change the group
569       UNI->Group = DGroup;
570       // For each member of the definers group
571       NodeGroupIterator DNGI(D);
572       while (NodeInfo *DNI = DNGI.next() ) {
573         // Remove internal edges
574         DGroup->addPending(-CountInternalUses(DNI, UNI));
575       }
576     }
577     // Merge the two lists
578     DGroup->group_insert(DGroup->group_end(),
579                          UGroup->group_begin(), UGroup->group_end());
580   } else if (DGroup) {
581     // Make user member of definers group
582     U->Group = DGroup;
583     // Add users uses to definers group pending
584     DGroup->addPending(U->Node->use_size());
585     // For each member of the definers group
586     NodeGroupIterator DNGI(D);
587     while (NodeInfo *DNI = DNGI.next() ) {
588       // Remove internal edges
589       DGroup->addPending(-CountInternalUses(DNI, U));
590     }
591     DGroup->group_push_back(U);
592   } else if (UGroup) {
593     // Make definer member of users group
594     D->Group = UGroup;
595     // Add definers uses to users group pending
596     UGroup->addPending(D->Node->use_size());
597     // For each member of the users group
598     NodeGroupIterator UNGI(U);
599     while (NodeInfo *UNI = UNGI.next() ) {
600       // Remove internal edges
601       UGroup->addPending(-CountInternalUses(D, UNI));
602     }
603     UGroup->group_insert(UGroup->group_begin(), D);
604   } else {
605     D->Group = U->Group = DGroup = new NodeGroup();
606     DGroup->addPending(D->Node->use_size() + U->Node->use_size() -
607                        CountInternalUses(D, U));
608     DGroup->group_push_back(D);
609     DGroup->group_push_back(U);
610     
611     if (HeadNG == NULL)
612       HeadNG = DGroup;
613     if (TailNG != NULL)
614       TailNG->Next = DGroup;
615     TailNG = DGroup;
616   }
617 }
618
619
620 /// print - Print ordering to specified output stream.
621 ///
622 void ScheduleDAGSimple::print(std::ostream &O) const {
623 #ifndef NDEBUG
624   O << "Ordering\n";
625   for (unsigned i = 0, N = Ordering.size(); i < N; i++) {
626     NodeInfo *NI = Ordering[i];
627     printNI(O, NI);
628     O << "\n";
629     if (NI->isGroupDominator()) {
630       NodeGroup *Group = NI->Group;
631       for (NIIterator NII = Group->group_begin(), E = Group->group_end();
632            NII != E; NII++) {
633         O << "    ";
634         printNI(O, *NII);
635         O << "\n";
636       }
637     }
638   }
639 #endif
640 }
641
642 void ScheduleDAGSimple::dump(const char *tag) const {
643   std::cerr << tag; dump();
644 }
645
646 void ScheduleDAGSimple::dump() const {
647   print(std::cerr);
648 }
649
650
651 /// EmitAll - Emit all nodes in schedule sorted order.
652 ///
653 void ScheduleDAGSimple::EmitAll() {
654   std::map<SDNode*, unsigned> VRBaseMap;
655   
656   // For each node in the ordering
657   for (unsigned i = 0, N = Ordering.size(); i < N; i++) {
658     // Get the scheduling info
659     NodeInfo *NI = Ordering[i];
660     if (NI->isInGroup()) {
661       NodeGroupIterator NGI(Ordering[i]);
662       while (NodeInfo *NI = NGI.next()) EmitNode(NI->Node, VRBaseMap);
663     } else {
664       EmitNode(NI->Node, VRBaseMap);
665     }
666   }
667 }
668
669 /// isFlagDefiner - Returns true if the node defines a flag result.
670 static bool isFlagDefiner(SDNode *A) {
671   unsigned N = A->getNumValues();
672   return N && A->getValueType(N - 1) == MVT::Flag;
673 }
674
675 /// isFlagUser - Returns true if the node uses a flag result.
676 ///
677 static bool isFlagUser(SDNode *A) {
678   unsigned N = A->getNumOperands();
679   return N && A->getOperand(N - 1).getValueType() == MVT::Flag;
680 }
681
682 /// printNI - Print node info.
683 ///
684 void ScheduleDAGSimple::printNI(std::ostream &O, NodeInfo *NI) const {
685 #ifndef NDEBUG
686   SDNode *Node = NI->Node;
687   O << " "
688     << std::hex << Node << std::dec
689     << ", Lat=" << NI->Latency
690     << ", Slot=" << NI->Slot
691     << ", ARITY=(" << Node->getNumOperands() << ","
692     << Node->getNumValues() << ")"
693     << " " << Node->getOperationName(&DAG);
694   if (isFlagDefiner(Node)) O << "<#";
695   if (isFlagUser(Node)) O << ">#";
696 #endif
697 }
698
699 /// printChanges - Hilight changes in order caused by scheduling.
700 ///
701 void ScheduleDAGSimple::printChanges(unsigned Index) const {
702 #ifndef NDEBUG
703   // Get the ordered node count
704   unsigned N = Ordering.size();
705   // Determine if any changes
706   unsigned i = 0;
707   for (; i < N; i++) {
708     NodeInfo *NI = Ordering[i];
709     if (NI->Preorder != i) break;
710   }
711   
712   if (i < N) {
713     std::cerr << Index << ". New Ordering\n";
714     
715     for (i = 0; i < N; i++) {
716       NodeInfo *NI = Ordering[i];
717       std::cerr << "  " << NI->Preorder << ". ";
718       printNI(std::cerr, NI);
719       std::cerr << "\n";
720       if (NI->isGroupDominator()) {
721         NodeGroup *Group = NI->Group;
722         for (NIIterator NII = Group->group_begin(), E = Group->group_end();
723              NII != E; NII++) {
724           std::cerr << "          ";
725           printNI(std::cerr, *NII);
726           std::cerr << "\n";
727         }
728       }
729     }
730   } else {
731     std::cerr << Index << ". No Changes\n";
732   }
733 #endif
734 }
735
736 //===----------------------------------------------------------------------===//
737 /// isDefiner - Return true if node A is a definer for B.
738 ///
739 bool ScheduleDAGSimple::isDefiner(NodeInfo *A, NodeInfo *B) {
740   // While there are A nodes
741   NodeGroupIterator NII(A);
742   while (NodeInfo *NI = NII.next()) {
743     // Extract node
744     SDNode *Node = NI->Node;
745     // While there operands in nodes of B
746     NodeGroupOpIterator NGOI(B);
747     while (!NGOI.isEnd()) {
748       SDOperand Op = NGOI.next();
749       // If node from A defines a node in B
750       if (Node == Op.Val) return true;
751     }
752   }
753   return false;
754 }
755
756 /// IncludeNode - Add node to NodeInfo vector.
757 ///
758 void ScheduleDAGSimple::IncludeNode(NodeInfo *NI) {
759   // Get node
760   SDNode *Node = NI->Node;
761   // Ignore entry node
762   if (Node->getOpcode() == ISD::EntryToken) return;
763   // Check current count for node
764   int Count = NI->getPending();
765   // If the node is already in list
766   if (Count < 0) return;
767   // Decrement count to indicate a visit
768   Count--;
769   // If count has gone to zero then add node to list
770   if (!Count) {
771     // Add node
772     if (NI->isInGroup()) {
773       Ordering.push_back(NI->Group->getDominator());
774     } else {
775       Ordering.push_back(NI);
776     }
777     // indicate node has been added
778     Count--;
779   }
780   // Mark as visited with new count 
781   NI->setPending(Count);
782 }
783
784 /// GatherSchedulingInfo - Get latency and resource information about each node.
785 ///
786 void ScheduleDAGSimple::GatherSchedulingInfo() {
787   // Get instruction itineraries for the target
788   const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
789   
790   // For each node
791   for (unsigned i = 0, N = NodeCount; i < N; i++) {
792     // Get node info
793     NodeInfo* NI = &Info[i];
794     SDNode *Node = NI->Node;
795     
796     // If there are itineraries and it is a machine instruction
797     if (InstrItins.isEmpty() || NoItins) {
798       // If machine opcode
799       if (Node->isTargetOpcode()) {
800         // Get return type to guess which processing unit 
801         MVT::ValueType VT = Node->getValueType(0);
802         // Get machine opcode
803         MachineOpCode TOpc = Node->getTargetOpcode();
804         NI->IsCall = TII->isCall(TOpc);
805         NI->IsLoad = TII->isLoad(TOpc);
806         NI->IsStore = TII->isStore(TOpc);
807
808         if (TII->isLoad(TOpc))             NI->StageBegin = &LoadStage;
809         else if (TII->isStore(TOpc))       NI->StageBegin = &StoreStage;
810         else if (MVT::isInteger(VT))       NI->StageBegin = &IntStage;
811         else if (MVT::isFloatingPoint(VT)) NI->StageBegin = &FloatStage;
812         if (NI->StageBegin) NI->StageEnd = NI->StageBegin + 1;
813       }
814     } else if (Node->isTargetOpcode()) {
815       // get machine opcode
816       MachineOpCode TOpc = Node->getTargetOpcode();
817       // Check to see if it is a call
818       NI->IsCall = TII->isCall(TOpc);
819       // Get itinerary stages for instruction
820       unsigned II = TII->getSchedClass(TOpc);
821       NI->StageBegin = InstrItins.begin(II);
822       NI->StageEnd = InstrItins.end(II);
823     }
824     
825     // One slot for the instruction itself
826     NI->Latency = 1;
827     
828     // Add long latency for a call to push it back in time
829     if (NI->IsCall) NI->Latency += CallLatency;
830     
831     // Sum up all the latencies
832     for (InstrStage *Stage = NI->StageBegin, *E = NI->StageEnd;
833         Stage != E; Stage++) {
834       NI->Latency += Stage->Cycles;
835     }
836     
837     // Sum up all the latencies for max tally size
838     NSlots += NI->Latency;
839   }
840   
841   // Unify metrics if in a group
842   if (HasGroups) {
843     for (unsigned i = 0, N = NodeCount; i < N; i++) {
844       NodeInfo* NI = &Info[i];
845       
846       if (NI->isInGroup()) {
847         NodeGroup *Group = NI->Group;
848         
849         if (!Group->getDominator()) {
850           NIIterator NGI = Group->group_begin(), NGE = Group->group_end();
851           NodeInfo *Dominator = *NGI;
852           unsigned Latency = 0;
853           
854           for (NGI++; NGI != NGE; NGI++) {
855             NodeInfo* NGNI = *NGI;
856             Latency += NGNI->Latency;
857             if (Dominator->Latency < NGNI->Latency) Dominator = NGNI;
858           }
859           
860           Dominator->Latency = Latency;
861           Group->setDominator(Dominator);
862         }
863       }
864     }
865   }
866 }
867
868 /// VisitAll - Visit each node breadth-wise to produce an initial ordering.
869 /// Note that the ordering in the Nodes vector is reversed.
870 void ScheduleDAGSimple::VisitAll() {
871   // Add first element to list
872   NodeInfo *NI = getNI(DAG.getRoot().Val);
873   if (NI->isInGroup()) {
874     Ordering.push_back(NI->Group->getDominator());
875   } else {
876     Ordering.push_back(NI);
877   }
878
879   // Iterate through all nodes that have been added
880   for (unsigned i = 0; i < Ordering.size(); i++) { // note: size() varies
881     // Visit all operands
882     NodeGroupOpIterator NGI(Ordering[i]);
883     while (!NGI.isEnd()) {
884       // Get next operand
885       SDOperand Op = NGI.next();
886       // Get node
887       SDNode *Node = Op.Val;
888       // Ignore passive nodes
889       if (isPassiveNode(Node)) continue;
890       // Check out node
891       IncludeNode(getNI(Node));
892     }
893   }
894
895   // Add entry node last (IncludeNode filters entry nodes)
896   if (DAG.getEntryNode().Val != DAG.getRoot().Val)
897     Ordering.push_back(getNI(DAG.getEntryNode().Val));
898     
899   // Reverse the order
900   std::reverse(Ordering.begin(), Ordering.end());
901 }
902
903 /// FakeGroupDominators - Set dominators for non-scheduling.
904 /// 
905 void ScheduleDAGSimple::FakeGroupDominators() {
906   for (unsigned i = 0, N = NodeCount; i < N; i++) {
907     NodeInfo* NI = &Info[i];
908     
909     if (NI->isInGroup()) {
910       NodeGroup *Group = NI->Group;
911       
912       if (!Group->getDominator()) {
913         Group->setDominator(NI);
914       }
915     }
916   }
917 }
918
919 /// isStrongDependency - Return true if node A has results used by node B. 
920 /// I.E., B must wait for latency of A.
921 bool ScheduleDAGSimple::isStrongDependency(NodeInfo *A, NodeInfo *B) {
922   // If A defines for B then it's a strong dependency or
923   // if a load follows a store (may be dependent but why take a chance.)
924   return isDefiner(A, B) || (A->IsStore && B->IsLoad);
925 }
926
927 /// isWeakDependency Return true if node A produces a result that will
928 /// conflict with operands of B.  It is assumed that we have called
929 /// isStrongDependency prior.
930 bool ScheduleDAGSimple::isWeakDependency(NodeInfo *A, NodeInfo *B) {
931   // TODO check for conflicting real registers and aliases
932 #if 0 // FIXME - Since we are in SSA form and not checking register aliasing
933   return A->Node->getOpcode() == ISD::EntryToken || isStrongDependency(B, A);
934 #else
935   return A->Node->getOpcode() == ISD::EntryToken;
936 #endif
937 }
938
939 /// ScheduleBackward - Schedule instructions so that any long latency
940 /// instructions and the critical path get pushed back in time. Time is run in
941 /// reverse to allow code reuse of the Tally and eliminate the overhead of
942 /// biasing every slot indices against NSlots.
943 void ScheduleDAGSimple::ScheduleBackward() {
944   // Size and clear the resource tally
945   Tally.Initialize(NSlots);
946   // Get number of nodes to schedule
947   unsigned N = Ordering.size();
948   
949   // For each node being scheduled
950   for (unsigned i = N; 0 < i--;) {
951     NodeInfo *NI = Ordering[i];
952     // Track insertion
953     unsigned Slot = NotFound;
954     
955     // Compare against those previously scheduled nodes
956     unsigned j = i + 1;
957     for (; j < N; j++) {
958       // Get following instruction
959       NodeInfo *Other = Ordering[j];
960       
961       // Check dependency against previously inserted nodes
962       if (isStrongDependency(NI, Other)) {
963         Slot = Other->Slot + Other->Latency;
964         break;
965       } else if (isWeakDependency(NI, Other)) {
966         Slot = Other->Slot;
967         break;
968       }
969     }
970     
971     // If independent of others (or first entry)
972     if (Slot == NotFound) Slot = 0;
973     
974 #if 0 // FIXME - measure later
975     // Find a slot where the needed resources are available
976     if (NI->StageBegin != NI->StageEnd)
977       Slot = Tally.FindAndReserve(Slot, NI->StageBegin, NI->StageEnd);
978 #endif
979       
980     // Set node slot
981     NI->Slot = Slot;
982     
983     // Insert sort based on slot
984     j = i + 1;
985     for (; j < N; j++) {
986       // Get following instruction
987       NodeInfo *Other = Ordering[j];
988       // Should we look further (remember slots are in reverse time)
989       if (Slot >= Other->Slot) break;
990       // Shuffle other into ordering
991       Ordering[j - 1] = Other;
992     }
993     // Insert node in proper slot
994     if (j != i + 1) Ordering[j - 1] = NI;
995   }
996 }
997
998 /// ScheduleForward - Schedule instructions to maximize packing.
999 ///
1000 void ScheduleDAGSimple::ScheduleForward() {
1001   // Size and clear the resource tally
1002   Tally.Initialize(NSlots);
1003   // Get number of nodes to schedule
1004   unsigned N = Ordering.size();
1005   
1006   // For each node being scheduled
1007   for (unsigned i = 0; i < N; i++) {
1008     NodeInfo *NI = Ordering[i];
1009     // Track insertion
1010     unsigned Slot = NotFound;
1011     
1012     // Compare against those previously scheduled nodes
1013     unsigned j = i;
1014     for (; 0 < j--;) {
1015       // Get following instruction
1016       NodeInfo *Other = Ordering[j];
1017       
1018       // Check dependency against previously inserted nodes
1019       if (isStrongDependency(Other, NI)) {
1020         Slot = Other->Slot + Other->Latency;
1021         break;
1022       } else if (Other->IsCall || isWeakDependency(Other, NI)) {
1023         Slot = Other->Slot;
1024         break;
1025       }
1026     }
1027     
1028     // If independent of others (or first entry)
1029     if (Slot == NotFound) Slot = 0;
1030     
1031     // Find a slot where the needed resources are available
1032     if (NI->StageBegin != NI->StageEnd)
1033       Slot = Tally.FindAndReserve(Slot, NI->StageBegin, NI->StageEnd);
1034       
1035     // Set node slot
1036     NI->Slot = Slot;
1037     
1038     // Insert sort based on slot
1039     j = i;
1040     for (; 0 < j--;) {
1041       // Get prior instruction
1042       NodeInfo *Other = Ordering[j];
1043       // Should we look further
1044       if (Slot >= Other->Slot) break;
1045       // Shuffle other into ordering
1046       Ordering[j + 1] = Other;
1047     }
1048     // Insert node in proper slot
1049     if (j != i) Ordering[j + 1] = NI;
1050   }
1051 }
1052
1053 /// Schedule - Order nodes according to selected style.
1054 ///
1055 void ScheduleDAGSimple::Schedule() {
1056   // Number the nodes
1057   NodeCount = std::distance(DAG.allnodes_begin(), DAG.allnodes_end());
1058
1059   // Set up minimum info for scheduling
1060   PrepareNodeInfo();
1061   // Construct node groups for flagged nodes
1062   IdentifyGroups();
1063   
1064   // Test to see if scheduling should occur
1065   bool ShouldSchedule = NodeCount > 3 && !NoSched;
1066   // Don't waste time if is only entry and return
1067   if (ShouldSchedule) {
1068     // Get latency and resource requirements
1069     GatherSchedulingInfo();
1070   } else if (HasGroups) {
1071     // Make sure all the groups have dominators
1072     FakeGroupDominators();
1073   }
1074
1075   // Breadth first walk of DAG
1076   VisitAll();
1077
1078 #ifndef NDEBUG
1079   static unsigned Count = 0;
1080   Count++;
1081   for (unsigned i = 0, N = Ordering.size(); i < N; i++) {
1082     NodeInfo *NI = Ordering[i];
1083     NI->Preorder = i;
1084   }
1085 #endif  
1086   
1087   // Don't waste time if is only entry and return
1088   if (ShouldSchedule) {
1089     // Push back long instructions and critical path
1090     ScheduleBackward();
1091     
1092     // Pack instructions to maximize resource utilization
1093     ScheduleForward();
1094   }
1095   
1096   DEBUG(printChanges(Count));
1097   
1098   // Emit in scheduled order
1099   EmitAll();
1100 }
1101
1102
1103 /// createSimpleDAGScheduler - This creates a simple two pass instruction
1104 /// scheduler.
1105 llvm::ScheduleDAG* llvm::createSimpleDAGScheduler(bool NoItins,
1106                                                   SelectionDAG &DAG,
1107                                                   MachineBasicBlock *BB) {
1108   return new ScheduleDAGSimple(false, NoItins, DAG, BB, DAG.getTarget());
1109 }
1110
1111 llvm::ScheduleDAG* llvm::createBFS_DAGScheduler(SelectionDAG &DAG,
1112                                                 MachineBasicBlock *BB) {
1113   return new ScheduleDAGSimple(true, false, DAG, BB,  DAG.getTarget());
1114 }