Renamed CCState members that appear to misspell 'Processed' as 'Proceed'. NFC.
[oota-llvm.git] / include / llvm / CodeGen / ScheduleDAG.h
1 //===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the ScheduleDAG class, which is used as the common
11 // base class for instruction schedulers. This encapsulates the scheduling DAG,
12 // which is shared between SelectionDAG and MachineInstr scheduling.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_CODEGEN_SCHEDULEDAG_H
17 #define LLVM_CODEGEN_SCHEDULEDAG_H
18
19 #include "llvm/ADT/BitVector.h"
20 #include "llvm/ADT/GraphTraits.h"
21 #include "llvm/ADT/PointerIntPair.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/CodeGen/MachineInstr.h"
24 #include "llvm/Target/TargetLowering.h"
25
26 namespace llvm {
27   class AliasAnalysis;
28   class SUnit;
29   class MachineConstantPool;
30   class MachineFunction;
31   class MachineRegisterInfo;
32   class MachineInstr;
33   struct MCSchedClassDesc;
34   class TargetRegisterInfo;
35   class ScheduleDAG;
36   class SDNode;
37   class TargetInstrInfo;
38   class MCInstrDesc;
39   class TargetMachine;
40   class TargetRegisterClass;
41   template<class Graph> class GraphWriter;
42
43   /// SDep - Scheduling dependency. This represents one direction of an
44   /// edge in the scheduling DAG.
45   class SDep {
46   public:
47     /// Kind - These are the different kinds of scheduling dependencies.
48     enum Kind {
49       Data,        ///< Regular data dependence (aka true-dependence).
50       Anti,        ///< A register anti-dependedence (aka WAR).
51       Output,      ///< A register output-dependence (aka WAW).
52       Order        ///< Any other ordering dependency.
53     };
54
55     // Strong dependencies must be respected by the scheduler. Artificial
56     // dependencies may be removed only if they are redundant with another
57     // strong depedence.
58     //
59     // Weak dependencies may be violated by the scheduling strategy, but only if
60     // the strategy can prove it is correct to do so.
61     //
62     // Strong OrderKinds must occur before "Weak".
63     // Weak OrderKinds must occur after "Weak".
64     enum OrderKind {
65       Barrier,      ///< An unknown scheduling barrier.
66       MayAliasMem,  ///< Nonvolatile load/Store instructions that may alias.
67       MustAliasMem, ///< Nonvolatile load/Store instructions that must alias.
68       Artificial,   ///< Arbitrary strong DAG edge (no real dependence).
69       Weak,         ///< Arbitrary weak DAG edge.
70       Cluster       ///< Weak DAG edge linking a chain of clustered instrs.
71     };
72
73   private:
74     /// Dep - A pointer to the depending/depended-on SUnit, and an enum
75     /// indicating the kind of the dependency.
76     PointerIntPair<SUnit *, 2, Kind> Dep;
77
78     /// Contents - A union discriminated by the dependence kind.
79     union {
80       /// Reg - For Data, Anti, and Output dependencies, the associated
81       /// register. For Data dependencies that don't currently have a register
82       /// assigned, this is set to zero.
83       unsigned Reg;
84
85       /// Order - Additional information about Order dependencies.
86       unsigned OrdKind; // enum OrderKind
87     } Contents;
88
89     /// Latency - The time associated with this edge. Often this is just
90     /// the value of the Latency field of the predecessor, however advanced
91     /// models may provide additional information about specific edges.
92     unsigned Latency;
93
94   public:
95     /// SDep - Construct a null SDep. This is only for use by container
96     /// classes which require default constructors. SUnits may not
97     /// have null SDep edges.
98     SDep() : Dep(nullptr, Data) {}
99
100     /// SDep - Construct an SDep with the specified values.
101     SDep(SUnit *S, Kind kind, unsigned Reg)
102       : Dep(S, kind), Contents() {
103       switch (kind) {
104       default:
105         llvm_unreachable("Reg given for non-register dependence!");
106       case Anti:
107       case Output:
108         assert(Reg != 0 &&
109                "SDep::Anti and SDep::Output must use a non-zero Reg!");
110         Contents.Reg = Reg;
111         Latency = 0;
112         break;
113       case Data:
114         Contents.Reg = Reg;
115         Latency = 1;
116         break;
117       }
118     }
119     SDep(SUnit *S, OrderKind kind)
120       : Dep(S, Order), Contents(), Latency(0) {
121       Contents.OrdKind = kind;
122     }
123
124     /// Return true if the specified SDep is equivalent except for latency.
125     bool overlaps(const SDep &Other) const {
126       if (Dep != Other.Dep) return false;
127       switch (Dep.getInt()) {
128       case Data:
129       case Anti:
130       case Output:
131         return Contents.Reg == Other.Contents.Reg;
132       case Order:
133         return Contents.OrdKind == Other.Contents.OrdKind;
134       }
135       llvm_unreachable("Invalid dependency kind!");
136     }
137
138     bool operator==(const SDep &Other) const {
139       return overlaps(Other) && Latency == Other.Latency;
140     }
141
142     bool operator!=(const SDep &Other) const {
143       return !operator==(Other);
144     }
145
146     /// getLatency - Return the latency value for this edge, which roughly
147     /// means the minimum number of cycles that must elapse between the
148     /// predecessor and the successor, given that they have this edge
149     /// between them.
150     unsigned getLatency() const {
151       return Latency;
152     }
153
154     /// setLatency - Set the latency for this edge.
155     void setLatency(unsigned Lat) {
156       Latency = Lat;
157     }
158
159     //// getSUnit - Return the SUnit to which this edge points.
160     SUnit *getSUnit() const {
161       return Dep.getPointer();
162     }
163
164     //// setSUnit - Assign the SUnit to which this edge points.
165     void setSUnit(SUnit *SU) {
166       Dep.setPointer(SU);
167     }
168
169     /// getKind - Return an enum value representing the kind of the dependence.
170     Kind getKind() const {
171       return Dep.getInt();
172     }
173
174     /// isCtrl - Shorthand for getKind() != SDep::Data.
175     bool isCtrl() const {
176       return getKind() != Data;
177     }
178
179     /// isNormalMemory - Test if this is an Order dependence between two
180     /// memory accesses where both sides of the dependence access memory
181     /// in non-volatile and fully modeled ways.
182     bool isNormalMemory() const {
183       return getKind() == Order && (Contents.OrdKind == MayAliasMem
184                                     || Contents.OrdKind == MustAliasMem);
185     }
186
187     /// isBarrier - Test if this is an Order dependence that is marked
188     /// as a barrier.
189     bool isBarrier() const {
190       return getKind() == Order && Contents.OrdKind == Barrier;
191     }
192
193     /// isMustAlias - Test if this is an Order dependence that is marked
194     /// as "must alias", meaning that the SUnits at either end of the edge
195     /// have a memory dependence on a known memory location.
196     bool isMustAlias() const {
197       return getKind() == Order && Contents.OrdKind == MustAliasMem;
198     }
199
200     /// isWeak - Test if this a weak dependence. Weak dependencies are
201     /// considered DAG edges for height computation and other heuristics, but do
202     /// not force ordering. Breaking a weak edge may require the scheduler to
203     /// compensate, for example by inserting a copy.
204     bool isWeak() const {
205       return getKind() == Order && Contents.OrdKind >= Weak;
206     }
207
208     /// isArtificial - Test if this is an Order dependence that is marked
209     /// as "artificial", meaning it isn't necessary for correctness.
210     bool isArtificial() const {
211       return getKind() == Order && Contents.OrdKind == Artificial;
212     }
213
214     /// isCluster - Test if this is an Order dependence that is marked
215     /// as "cluster", meaning it is artificial and wants to be adjacent.
216     bool isCluster() const {
217       return getKind() == Order && Contents.OrdKind == Cluster;
218     }
219
220     /// isAssignedRegDep - Test if this is a Data dependence that is
221     /// associated with a register.
222     bool isAssignedRegDep() const {
223       return getKind() == Data && Contents.Reg != 0;
224     }
225
226     /// getReg - Return the register associated with this edge. This is
227     /// only valid on Data, Anti, and Output edges. On Data edges, this
228     /// value may be zero, meaning there is no associated register.
229     unsigned getReg() const {
230       assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
231              "getReg called on non-register dependence edge!");
232       return Contents.Reg;
233     }
234
235     /// setReg - Assign the associated register for this edge. This is
236     /// only valid on Data, Anti, and Output edges. On Anti and Output
237     /// edges, this value must not be zero. On Data edges, the value may
238     /// be zero, which would mean that no specific register is associated
239     /// with this edge.
240     void setReg(unsigned Reg) {
241       assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
242              "setReg called on non-register dependence edge!");
243       assert((getKind() != Anti || Reg != 0) &&
244              "SDep::Anti edge cannot use the zero register!");
245       assert((getKind() != Output || Reg != 0) &&
246              "SDep::Output edge cannot use the zero register!");
247       Contents.Reg = Reg;
248     }
249   };
250
251   template <>
252   struct isPodLike<SDep> { static const bool value = true; };
253
254   /// SUnit - Scheduling unit. This is a node in the scheduling DAG.
255   class SUnit {
256   private:
257     enum : unsigned { BoundaryID = ~0u };
258
259     SDNode *Node;                       // Representative node.
260     MachineInstr *Instr;                // Alternatively, a MachineInstr.
261   public:
262     SUnit *OrigNode;                    // If not this, the node from which
263                                         // this node was cloned.
264                                         // (SD scheduling only)
265
266     const MCSchedClassDesc *SchedClass; // NULL or resolved SchedClass.
267
268     // Preds/Succs - The SUnits before/after us in the graph.
269     SmallVector<SDep, 4> Preds;  // All sunit predecessors.
270     SmallVector<SDep, 4> Succs;  // All sunit successors.
271
272     typedef SmallVectorImpl<SDep>::iterator pred_iterator;
273     typedef SmallVectorImpl<SDep>::iterator succ_iterator;
274     typedef SmallVectorImpl<SDep>::const_iterator const_pred_iterator;
275     typedef SmallVectorImpl<SDep>::const_iterator const_succ_iterator;
276
277     unsigned NodeNum;                   // Entry # of node in the node vector.
278     unsigned NodeQueueId;               // Queue id of node.
279     unsigned NumPreds;                  // # of SDep::Data preds.
280     unsigned NumSuccs;                  // # of SDep::Data sucss.
281     unsigned NumPredsLeft;              // # of preds not scheduled.
282     unsigned NumSuccsLeft;              // # of succs not scheduled.
283     unsigned WeakPredsLeft;             // # of weak preds not scheduled.
284     unsigned WeakSuccsLeft;             // # of weak succs not scheduled.
285     unsigned short NumRegDefsLeft;      // # of reg defs with no scheduled use.
286     unsigned short Latency;             // Node latency.
287     bool isVRegCycle      : 1;          // May use and def the same vreg.
288     bool isCall           : 1;          // Is a function call.
289     bool isCallOp         : 1;          // Is a function call operand.
290     bool isTwoAddress     : 1;          // Is a two-address instruction.
291     bool isCommutable     : 1;          // Is a commutable instruction.
292     bool hasPhysRegUses   : 1;          // Has physreg uses.
293     bool hasPhysRegDefs   : 1;          // Has physreg defs that are being used.
294     bool hasPhysRegClobbers : 1;        // Has any physreg defs, used or not.
295     bool isPending        : 1;          // True once pending.
296     bool isAvailable      : 1;          // True once available.
297     bool isScheduled      : 1;          // True once scheduled.
298     bool isScheduleHigh   : 1;          // True if preferable to schedule high.
299     bool isScheduleLow    : 1;          // True if preferable to schedule low.
300     bool isCloned         : 1;          // True if this node has been cloned.
301     bool isUnbuffered     : 1;          // Uses an unbuffered resource.
302     bool hasReservedResource : 1;       // Uses a reserved resource.
303     Sched::Preference SchedulingPref;   // Scheduling preference.
304
305   private:
306     bool isDepthCurrent   : 1;          // True if Depth is current.
307     bool isHeightCurrent  : 1;          // True if Height is current.
308     unsigned Depth;                     // Node depth.
309     unsigned Height;                    // Node height.
310   public:
311     unsigned TopReadyCycle; // Cycle relative to start when node is ready.
312     unsigned BotReadyCycle; // Cycle relative to end when node is ready.
313
314     const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
315     const TargetRegisterClass *CopySrcRC;
316
317     /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
318     /// an SDNode and any nodes flagged to it.
319     SUnit(SDNode *node, unsigned nodenum)
320       : Node(node), Instr(nullptr), OrigNode(nullptr), SchedClass(nullptr),
321         NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0),
322         NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
323         NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
324         isCallOp(false), isTwoAddress(false), isCommutable(false),
325         hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
326         isPending(false), isAvailable(false), isScheduled(false),
327         isScheduleHigh(false), isScheduleLow(false), isCloned(false),
328         isUnbuffered(false), hasReservedResource(false),
329         SchedulingPref(Sched::None), isDepthCurrent(false),
330         isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
331         BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}
332
333     /// SUnit - Construct an SUnit for post-regalloc scheduling to represent
334     /// a MachineInstr.
335     SUnit(MachineInstr *instr, unsigned nodenum)
336       : Node(nullptr), Instr(instr), OrigNode(nullptr), SchedClass(nullptr),
337         NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0),
338         NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
339         NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
340         isCallOp(false), isTwoAddress(false), isCommutable(false),
341         hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
342         isPending(false), isAvailable(false), isScheduled(false),
343         isScheduleHigh(false), isScheduleLow(false), isCloned(false),
344         isUnbuffered(false), hasReservedResource(false),
345         SchedulingPref(Sched::None), isDepthCurrent(false),
346         isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
347         BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}
348
349     /// SUnit - Construct a placeholder SUnit.
350     SUnit()
351       : Node(nullptr), Instr(nullptr), OrigNode(nullptr), SchedClass(nullptr),
352         NodeNum(BoundaryID), NodeQueueId(0), NumPreds(0), NumSuccs(0),
353         NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
354         NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
355         isCallOp(false), isTwoAddress(false), isCommutable(false),
356         hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
357         isPending(false), isAvailable(false), isScheduled(false),
358         isScheduleHigh(false), isScheduleLow(false), isCloned(false),
359         isUnbuffered(false), hasReservedResource(false),
360         SchedulingPref(Sched::None), isDepthCurrent(false),
361         isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
362         BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}
363
364     /// \brief Boundary nodes are placeholders for the boundary of the
365     /// scheduling region.
366     ///
367     /// BoundaryNodes can have DAG edges, including Data edges, but they do not
368     /// correspond to schedulable entities (e.g. instructions) and do not have a
369     /// valid ID. Consequently, always check for boundary nodes before accessing
370     /// an assoicative data structure keyed on node ID.
371     bool isBoundaryNode() const { return NodeNum == BoundaryID; };
372
373     /// setNode - Assign the representative SDNode for this SUnit.
374     /// This may be used during pre-regalloc scheduling.
375     void setNode(SDNode *N) {
376       assert(!Instr && "Setting SDNode of SUnit with MachineInstr!");
377       Node = N;
378     }
379
380     /// getNode - Return the representative SDNode for this SUnit.
381     /// This may be used during pre-regalloc scheduling.
382     SDNode *getNode() const {
383       assert(!Instr && "Reading SDNode of SUnit with MachineInstr!");
384       return Node;
385     }
386
387     /// isInstr - Return true if this SUnit refers to a machine instruction as
388     /// opposed to an SDNode.
389     bool isInstr() const { return Instr; }
390
391     /// setInstr - Assign the instruction for the SUnit.
392     /// This may be used during post-regalloc scheduling.
393     void setInstr(MachineInstr *MI) {
394       assert(!Node && "Setting MachineInstr of SUnit with SDNode!");
395       Instr = MI;
396     }
397
398     /// getInstr - Return the representative MachineInstr for this SUnit.
399     /// This may be used during post-regalloc scheduling.
400     MachineInstr *getInstr() const {
401       assert(!Node && "Reading MachineInstr of SUnit with SDNode!");
402       return Instr;
403     }
404
405     /// addPred - This adds the specified edge as a pred of the current node if
406     /// not already.  It also adds the current node as a successor of the
407     /// specified node.
408     bool addPred(const SDep &D, bool Required = true);
409
410     /// removePred - This removes the specified edge as a pred of the current
411     /// node if it exists.  It also removes the current node as a successor of
412     /// the specified node.
413     void removePred(const SDep &D);
414
415     /// getDepth - Return the depth of this node, which is the length of the
416     /// maximum path up to any node which has no predecessors.
417     unsigned getDepth() const {
418       if (!isDepthCurrent)
419         const_cast<SUnit *>(this)->ComputeDepth();
420       return Depth;
421     }
422
423     /// getHeight - Return the height of this node, which is the length of the
424     /// maximum path down to any node which has no successors.
425     unsigned getHeight() const {
426       if (!isHeightCurrent)
427         const_cast<SUnit *>(this)->ComputeHeight();
428       return Height;
429     }
430
431     /// setDepthToAtLeast - If NewDepth is greater than this node's
432     /// depth value, set it to be the new depth value. This also
433     /// recursively marks successor nodes dirty.
434     void setDepthToAtLeast(unsigned NewDepth);
435
436     /// setDepthToAtLeast - If NewDepth is greater than this node's
437     /// depth value, set it to be the new height value. This also
438     /// recursively marks predecessor nodes dirty.
439     void setHeightToAtLeast(unsigned NewHeight);
440
441     /// setDepthDirty - Set a flag in this node to indicate that its
442     /// stored Depth value will require recomputation the next time
443     /// getDepth() is called.
444     void setDepthDirty();
445
446     /// setHeightDirty - Set a flag in this node to indicate that its
447     /// stored Height value will require recomputation the next time
448     /// getHeight() is called.
449     void setHeightDirty();
450
451     /// isPred - Test if node N is a predecessor of this node.
452     bool isPred(SUnit *N) {
453       for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
454         if (Preds[i].getSUnit() == N)
455           return true;
456       return false;
457     }
458
459     /// isSucc - Test if node N is a successor of this node.
460     bool isSucc(SUnit *N) {
461       for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
462         if (Succs[i].getSUnit() == N)
463           return true;
464       return false;
465     }
466
467     bool isTopReady() const {
468       return NumPredsLeft == 0;
469     }
470     bool isBottomReady() const {
471       return NumSuccsLeft == 0;
472     }
473
474     /// \brief Order this node's predecessor edges such that the critical path
475     /// edge occurs first.
476     void biasCriticalPath();
477
478     void dump(const ScheduleDAG *G) const;
479     void dumpAll(const ScheduleDAG *G) const;
480     void print(raw_ostream &O, const ScheduleDAG *G) const;
481
482   private:
483     void ComputeDepth();
484     void ComputeHeight();
485   };
486
487   //===--------------------------------------------------------------------===//
488   /// SchedulingPriorityQueue - This interface is used to plug different
489   /// priorities computation algorithms into the list scheduler. It implements
490   /// the interface of a standard priority queue, where nodes are inserted in
491   /// arbitrary order and returned in priority order.  The computation of the
492   /// priority and the representation of the queue are totally up to the
493   /// implementation to decide.
494   ///
495   class SchedulingPriorityQueue {
496     virtual void anchor();
497     unsigned CurCycle;
498     bool HasReadyFilter;
499   public:
500     SchedulingPriorityQueue(bool rf = false):
501       CurCycle(0), HasReadyFilter(rf) {}
502     virtual ~SchedulingPriorityQueue() {}
503
504     virtual bool isBottomUp() const = 0;
505
506     virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
507     virtual void addNode(const SUnit *SU) = 0;
508     virtual void updateNode(const SUnit *SU) = 0;
509     virtual void releaseState() = 0;
510
511     virtual bool empty() const = 0;
512
513     bool hasReadyFilter() const { return HasReadyFilter; }
514
515     virtual bool tracksRegPressure() const { return false; }
516
517     virtual bool isReady(SUnit *) const {
518       assert(!HasReadyFilter && "The ready filter must override isReady()");
519       return true;
520     }
521     virtual void push(SUnit *U) = 0;
522
523     void push_all(const std::vector<SUnit *> &Nodes) {
524       for (std::vector<SUnit *>::const_iterator I = Nodes.begin(),
525            E = Nodes.end(); I != E; ++I)
526         push(*I);
527     }
528
529     virtual SUnit *pop() = 0;
530
531     virtual void remove(SUnit *SU) = 0;
532
533     virtual void dump(ScheduleDAG *) const {}
534
535     /// scheduledNode - As each node is scheduled, this method is invoked.  This
536     /// allows the priority function to adjust the priority of related
537     /// unscheduled nodes, for example.
538     ///
539     virtual void scheduledNode(SUnit *) {}
540
541     virtual void unscheduledNode(SUnit *) {}
542
543     void setCurCycle(unsigned Cycle) {
544       CurCycle = Cycle;
545     }
546
547     unsigned getCurCycle() const {
548       return CurCycle;
549     }
550   };
551
552   class ScheduleDAG {
553   public:
554     const TargetMachine &TM;              // Target processor
555     const TargetInstrInfo *TII;           // Target instruction information
556     const TargetRegisterInfo *TRI;        // Target processor register info
557     MachineFunction &MF;                  // Machine function
558     MachineRegisterInfo &MRI;             // Virtual/real register map
559     std::vector<SUnit> SUnits;            // The scheduling units.
560     SUnit EntrySU;                        // Special node for the region entry.
561     SUnit ExitSU;                         // Special node for the region exit.
562
563 #ifdef NDEBUG
564     static const bool StressSched = false;
565 #else
566     bool StressSched;
567 #endif
568
569     explicit ScheduleDAG(MachineFunction &mf);
570
571     virtual ~ScheduleDAG();
572
573     /// clearDAG - clear the DAG state (between regions).
574     void clearDAG();
575
576     /// getInstrDesc - Return the MCInstrDesc of this SUnit.
577     /// Return NULL for SDNodes without a machine opcode.
578     const MCInstrDesc *getInstrDesc(const SUnit *SU) const {
579       if (SU->isInstr()) return &SU->getInstr()->getDesc();
580       return getNodeDesc(SU->getNode());
581     }
582
583     /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
584     /// using 'dot'.
585     ///
586     virtual void viewGraph(const Twine &Name, const Twine &Title);
587     virtual void viewGraph();
588
589     virtual void dumpNode(const SUnit *SU) const = 0;
590
591     /// getGraphNodeLabel - Return a label for an SUnit node in a visualization
592     /// of the ScheduleDAG.
593     virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0;
594
595     /// getDAGLabel - Return a label for the region of code covered by the DAG.
596     virtual std::string getDAGName() const = 0;
597
598     /// addCustomGraphFeatures - Add custom features for a visualization of
599     /// the ScheduleDAG.
600     virtual void addCustomGraphFeatures(GraphWriter<ScheduleDAG*> &) const {}
601
602 #ifndef NDEBUG
603     /// VerifyScheduledDAG - Verify that all SUnits were scheduled and that
604     /// their state is consistent. Return the number of scheduled SUnits.
605     unsigned VerifyScheduledDAG(bool isBottomUp);
606 #endif
607
608   private:
609     // Return the MCInstrDesc of this SDNode or NULL.
610     const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
611   };
612
613   class SUnitIterator : public std::iterator<std::forward_iterator_tag,
614                                              SUnit, ptrdiff_t> {
615     SUnit *Node;
616     unsigned Operand;
617
618     SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
619   public:
620     bool operator==(const SUnitIterator& x) const {
621       return Operand == x.Operand;
622     }
623     bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
624
625     const SUnitIterator &operator=(const SUnitIterator &I) {
626       assert(I.Node==Node && "Cannot assign iterators to two different nodes!");
627       Operand = I.Operand;
628       return *this;
629     }
630
631     pointer operator*() const {
632       return Node->Preds[Operand].getSUnit();
633     }
634     pointer operator->() const { return operator*(); }
635
636     SUnitIterator& operator++() {                // Preincrement
637       ++Operand;
638       return *this;
639     }
640     SUnitIterator operator++(int) { // Postincrement
641       SUnitIterator tmp = *this; ++*this; return tmp;
642     }
643
644     static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
645     static SUnitIterator end  (SUnit *N) {
646       return SUnitIterator(N, (unsigned)N->Preds.size());
647     }
648
649     unsigned getOperand() const { return Operand; }
650     const SUnit *getNode() const { return Node; }
651     /// isCtrlDep - Test if this is not an SDep::Data dependence.
652     bool isCtrlDep() const {
653       return getSDep().isCtrl();
654     }
655     bool isArtificialDep() const {
656       return getSDep().isArtificial();
657     }
658     const SDep &getSDep() const {
659       return Node->Preds[Operand];
660     }
661   };
662
663   template <> struct GraphTraits<SUnit*> {
664     typedef SUnit NodeType;
665     typedef SUnitIterator ChildIteratorType;
666     static inline NodeType *getEntryNode(SUnit *N) { return N; }
667     static inline ChildIteratorType child_begin(NodeType *N) {
668       return SUnitIterator::begin(N);
669     }
670     static inline ChildIteratorType child_end(NodeType *N) {
671       return SUnitIterator::end(N);
672     }
673   };
674
675   template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
676     typedef std::vector<SUnit>::iterator nodes_iterator;
677     static nodes_iterator nodes_begin(ScheduleDAG *G) {
678       return G->SUnits.begin();
679     }
680     static nodes_iterator nodes_end(ScheduleDAG *G) {
681       return G->SUnits.end();
682     }
683   };
684
685   /// ScheduleDAGTopologicalSort is a class that computes a topological
686   /// ordering for SUnits and provides methods for dynamically updating
687   /// the ordering as new edges are added.
688   ///
689   /// This allows a very fast implementation of IsReachable, for example.
690   ///
691   class ScheduleDAGTopologicalSort {
692     /// SUnits - A reference to the ScheduleDAG's SUnits.
693     std::vector<SUnit> &SUnits;
694     SUnit *ExitSU;
695
696     /// Index2Node - Maps topological index to the node number.
697     std::vector<int> Index2Node;
698     /// Node2Index - Maps the node number to its topological index.
699     std::vector<int> Node2Index;
700     /// Visited - a set of nodes visited during a DFS traversal.
701     BitVector Visited;
702
703     /// DFS - make a DFS traversal and mark all nodes affected by the
704     /// edge insertion. These nodes will later get new topological indexes
705     /// by means of the Shift method.
706     void DFS(const SUnit *SU, int UpperBound, bool& HasLoop);
707
708     /// Shift - reassign topological indexes for the nodes in the DAG
709     /// to preserve the topological ordering.
710     void Shift(BitVector& Visited, int LowerBound, int UpperBound);
711
712     /// Allocate - assign the topological index to the node n.
713     void Allocate(int n, int index);
714
715   public:
716     ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, SUnit *ExitSU);
717
718     /// InitDAGTopologicalSorting - create the initial topological
719     /// ordering from the DAG to be scheduled.
720     void InitDAGTopologicalSorting();
721
722     /// IsReachable - Checks if SU is reachable from TargetSU.
723     bool IsReachable(const SUnit *SU, const SUnit *TargetSU);
724
725     /// WillCreateCycle - Return true if addPred(TargetSU, SU) creates a cycle.
726     bool WillCreateCycle(SUnit *TargetSU, SUnit *SU);
727
728     /// AddPred - Updates the topological ordering to accommodate an edge
729     /// to be added from SUnit X to SUnit Y.
730     void AddPred(SUnit *Y, SUnit *X);
731
732     /// RemovePred - Updates the topological ordering to accommodate an
733     /// an edge to be removed from the specified node N from the predecessors
734     /// of the current node M.
735     void RemovePred(SUnit *M, SUnit *N);
736
737     typedef std::vector<int>::iterator iterator;
738     typedef std::vector<int>::const_iterator const_iterator;
739     iterator begin() { return Index2Node.begin(); }
740     const_iterator begin() const { return Index2Node.begin(); }
741     iterator end() { return Index2Node.end(); }
742     const_iterator end() const { return Index2Node.end(); }
743
744     typedef std::vector<int>::reverse_iterator reverse_iterator;
745     typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
746     reverse_iterator rbegin() { return Index2Node.rbegin(); }
747     const_reverse_iterator rbegin() const { return Index2Node.rbegin(); }
748     reverse_iterator rend() { return Index2Node.rend(); }
749     const_reverse_iterator rend() const { return Index2Node.rend(); }
750   };
751 }
752
753 #endif