1 //===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_CODEGEN_SCHEDULEDAG_H
17 #define LLVM_CODEGEN_SCHEDULEDAG_H
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"
29 class MachineConstantPool;
30 class MachineFunction;
31 class MachineRegisterInfo;
33 struct MCSchedClassDesc;
34 class TargetRegisterInfo;
37 class TargetInstrInfo;
40 class TargetRegisterClass;
41 template<class Graph> class GraphWriter;
43 /// SDep - Scheduling dependency. This represents one direction of an
44 /// edge in the scheduling DAG.
47 /// Kind - These are the different kinds of scheduling dependencies.
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.
55 // Strong dependencies must be respected by the scheduler. Artificial
56 // dependencies may be removed only if they are redundant with another
59 // Weak dependencies may be violated by the scheduling strategy, but only if
60 // the strategy can prove it is correct to do so.
62 // Strong OrderKinds must occur before "Weak".
63 // Weak OrderKinds must occur after "Weak".
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.
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;
78 /// Contents - A union discriminated by the dependence kind.
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.
85 /// Order - Additional information about Order dependencies.
86 unsigned OrdKind; // enum OrderKind
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.
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(0, Data) {}
100 /// SDep - Construct an SDep with the specified values.
101 SDep(SUnit *S, Kind kind, unsigned Reg)
102 : Dep(S, kind), Contents() {
105 llvm_unreachable("Reg given for non-register dependence!");
109 "SDep::Anti and SDep::Output must use a non-zero Reg!");
119 SDep(SUnit *S, OrderKind kind)
120 : Dep(S, Order), Contents(), Latency(0) {
121 Contents.OrdKind = kind;
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()) {
131 return Contents.Reg == Other.Contents.Reg;
133 return Contents.OrdKind == Other.Contents.OrdKind;
135 llvm_unreachable("Invalid dependency kind!");
138 bool operator==(const SDep &Other) const {
139 return overlaps(Other) && Latency == Other.Latency;
142 bool operator!=(const SDep &Other) const {
143 return !operator==(Other);
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
150 unsigned getLatency() const {
154 /// setLatency - Set the latency for this edge.
155 void setLatency(unsigned Lat) {
159 //// getSUnit - Return the SUnit to which this edge points.
160 SUnit *getSUnit() const {
161 return Dep.getPointer();
164 //// setSUnit - Assign the SUnit to which this edge points.
165 void setSUnit(SUnit *SU) {
169 /// getKind - Return an enum value representing the kind of the dependence.
170 Kind getKind() const {
174 /// isCtrl - Shorthand for getKind() != SDep::Data.
175 bool isCtrl() const {
176 return getKind() != Data;
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);
187 /// isMustAlias - Test if this is an Order dependence that is marked
188 /// as "must alias", meaning that the SUnits at either end of the edge
189 /// have a memory dependence on a known memory location.
190 bool isMustAlias() const {
191 return getKind() == Order && Contents.OrdKind == MustAliasMem;
194 /// isWeak - Test if this a weak dependence. Weak dependencies are
195 /// considered DAG edges for height computation and other heuristics, but do
196 /// not force ordering. Breaking a weak edge may require the scheduler to
197 /// compensate, for example by inserting a copy.
198 bool isWeak() const {
199 return getKind() == Order && Contents.OrdKind >= Weak;
202 /// isArtificial - Test if this is an Order dependence that is marked
203 /// as "artificial", meaning it isn't necessary for correctness.
204 bool isArtificial() const {
205 return getKind() == Order && Contents.OrdKind == Artificial;
208 /// isCluster - Test if this is an Order dependence that is marked
209 /// as "cluster", meaning it is artificial and wants to be adjacent.
210 bool isCluster() const {
211 return getKind() == Order && Contents.OrdKind == Cluster;
214 /// isAssignedRegDep - Test if this is a Data dependence that is
215 /// associated with a register.
216 bool isAssignedRegDep() const {
217 return getKind() == Data && Contents.Reg != 0;
220 /// getReg - Return the register associated with this edge. This is
221 /// only valid on Data, Anti, and Output edges. On Data edges, this
222 /// value may be zero, meaning there is no associated register.
223 unsigned getReg() const {
224 assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
225 "getReg called on non-register dependence edge!");
229 /// setReg - Assign the associated register for this edge. This is
230 /// only valid on Data, Anti, and Output edges. On Anti and Output
231 /// edges, this value must not be zero. On Data edges, the value may
232 /// be zero, which would mean that no specific register is associated
234 void setReg(unsigned Reg) {
235 assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
236 "setReg called on non-register dependence edge!");
237 assert((getKind() != Anti || Reg != 0) &&
238 "SDep::Anti edge cannot use the zero register!");
239 assert((getKind() != Output || Reg != 0) &&
240 "SDep::Output edge cannot use the zero register!");
246 struct isPodLike<SDep> { static const bool value = true; };
248 /// SUnit - Scheduling unit. This is a node in the scheduling DAG.
251 enum LLVM_ENUM_INT_TYPE(unsigned) { BoundaryID = ~0u };
253 SDNode *Node; // Representative node.
254 MachineInstr *Instr; // Alternatively, a MachineInstr.
256 SUnit *OrigNode; // If not this, the node from which
257 // this node was cloned.
258 // (SD scheduling only)
260 const MCSchedClassDesc *SchedClass; // NULL or resolved SchedClass.
262 // Preds/Succs - The SUnits before/after us in the graph.
263 SmallVector<SDep, 4> Preds; // All sunit predecessors.
264 SmallVector<SDep, 4> Succs; // All sunit successors.
266 typedef SmallVectorImpl<SDep>::iterator pred_iterator;
267 typedef SmallVectorImpl<SDep>::iterator succ_iterator;
268 typedef SmallVectorImpl<SDep>::const_iterator const_pred_iterator;
269 typedef SmallVectorImpl<SDep>::const_iterator const_succ_iterator;
271 unsigned NodeNum; // Entry # of node in the node vector.
272 unsigned NodeQueueId; // Queue id of node.
273 unsigned NumPreds; // # of SDep::Data preds.
274 unsigned NumSuccs; // # of SDep::Data sucss.
275 unsigned NumPredsLeft; // # of preds not scheduled.
276 unsigned NumSuccsLeft; // # of succs not scheduled.
277 unsigned WeakPredsLeft; // # of weak preds not scheduled.
278 unsigned WeakSuccsLeft; // # of weak succs not scheduled.
279 unsigned short NumRegDefsLeft; // # of reg defs with no scheduled use.
280 unsigned short Latency; // Node latency.
281 bool isVRegCycle : 1; // May use and def the same vreg.
282 bool isCall : 1; // Is a function call.
283 bool isCallOp : 1; // Is a function call operand.
284 bool isTwoAddress : 1; // Is a two-address instruction.
285 bool isCommutable : 1; // Is a commutable instruction.
286 bool hasPhysRegUses : 1; // Has physreg uses.
287 bool hasPhysRegDefs : 1; // Has physreg defs that are being used.
288 bool hasPhysRegClobbers : 1; // Has any physreg defs, used or not.
289 bool isPending : 1; // True once pending.
290 bool isAvailable : 1; // True once available.
291 bool isScheduled : 1; // True once scheduled.
292 bool isScheduleHigh : 1; // True if preferable to schedule high.
293 bool isScheduleLow : 1; // True if preferable to schedule low.
294 bool isCloned : 1; // True if this node has been cloned.
295 bool isUnbuffered : 1; // Uses an unbuffered resource.
296 bool hasReservedResource : 1; // Uses a reserved resource.
297 Sched::Preference SchedulingPref; // Scheduling preference.
300 bool isDepthCurrent : 1; // True if Depth is current.
301 bool isHeightCurrent : 1; // True if Height is current.
302 unsigned Depth; // Node depth.
303 unsigned Height; // Node height.
305 unsigned TopReadyCycle; // Cycle relative to start when node is ready.
306 unsigned BotReadyCycle; // Cycle relative to end when node is ready.
308 const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
309 const TargetRegisterClass *CopySrcRC;
311 /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
312 /// an SDNode and any nodes flagged to it.
313 SUnit(SDNode *node, unsigned nodenum)
314 : Node(node), Instr(0), OrigNode(0), SchedClass(0), NodeNum(nodenum),
315 NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
316 NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0),
317 Latency(0), isVRegCycle(false), isCall(false), isCallOp(false),
318 isTwoAddress(false), isCommutable(false), hasPhysRegUses(false),
319 hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false),
320 isAvailable(false), isScheduled(false), isScheduleHigh(false),
321 isScheduleLow(false), isCloned(false), isUnbuffered(false),
322 hasReservedResource(false), SchedulingPref(Sched::None),
323 isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
324 TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
326 /// SUnit - Construct an SUnit for post-regalloc scheduling to represent
328 SUnit(MachineInstr *instr, unsigned nodenum)
329 : Node(0), Instr(instr), OrigNode(0), SchedClass(0), NodeNum(nodenum),
330 NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
331 NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0),
332 Latency(0), isVRegCycle(false), isCall(false), isCallOp(false),
333 isTwoAddress(false), isCommutable(false), hasPhysRegUses(false),
334 hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false),
335 isAvailable(false), isScheduled(false), isScheduleHigh(false),
336 isScheduleLow(false), isCloned(false), isUnbuffered(false),
337 hasReservedResource(false), SchedulingPref(Sched::None),
338 isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
339 TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
341 /// SUnit - Construct a placeholder SUnit.
343 : Node(0), Instr(0), OrigNode(0), SchedClass(0), NodeNum(BoundaryID),
344 NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
345 NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0),
346 Latency(0), isVRegCycle(false), isCall(false), isCallOp(false),
347 isTwoAddress(false), isCommutable(false), hasPhysRegUses(false),
348 hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false),
349 isAvailable(false), isScheduled(false), isScheduleHigh(false),
350 isScheduleLow(false), isCloned(false), isUnbuffered(false),
351 hasReservedResource(false), SchedulingPref(Sched::None),
352 isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
353 TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
355 /// \brief Boundary nodes are placeholders for the boundary of the
356 /// scheduling region.
358 /// BoundaryNodes can have DAG edges, including Data edges, but they do not
359 /// correspond to schedulable entities (e.g. instructions) and do not have a
360 /// valid ID. Consequently, always check for boundary nodes before accessing
361 /// an assoicative data structure keyed on node ID.
362 bool isBoundaryNode() const { return NodeNum == BoundaryID; };
364 /// setNode - Assign the representative SDNode for this SUnit.
365 /// This may be used during pre-regalloc scheduling.
366 void setNode(SDNode *N) {
367 assert(!Instr && "Setting SDNode of SUnit with MachineInstr!");
371 /// getNode - Return the representative SDNode for this SUnit.
372 /// This may be used during pre-regalloc scheduling.
373 SDNode *getNode() const {
374 assert(!Instr && "Reading SDNode of SUnit with MachineInstr!");
378 /// isInstr - Return true if this SUnit refers to a machine instruction as
379 /// opposed to an SDNode.
380 bool isInstr() const { return Instr; }
382 /// setInstr - Assign the instruction for the SUnit.
383 /// This may be used during post-regalloc scheduling.
384 void setInstr(MachineInstr *MI) {
385 assert(!Node && "Setting MachineInstr of SUnit with SDNode!");
389 /// getInstr - Return the representative MachineInstr for this SUnit.
390 /// This may be used during post-regalloc scheduling.
391 MachineInstr *getInstr() const {
392 assert(!Node && "Reading MachineInstr of SUnit with SDNode!");
396 /// addPred - This adds the specified edge as a pred of the current node if
397 /// not already. It also adds the current node as a successor of the
399 bool addPred(const SDep &D, bool Required = true);
401 /// removePred - This removes the specified edge as a pred of the current
402 /// node if it exists. It also removes the current node as a successor of
403 /// the specified node.
404 void removePred(const SDep &D);
406 /// getDepth - Return the depth of this node, which is the length of the
407 /// maximum path up to any node which has no predecessors.
408 unsigned getDepth() const {
410 const_cast<SUnit *>(this)->ComputeDepth();
414 /// getHeight - Return the height of this node, which is the length of the
415 /// maximum path down to any node which has no successors.
416 unsigned getHeight() const {
417 if (!isHeightCurrent)
418 const_cast<SUnit *>(this)->ComputeHeight();
422 /// setDepthToAtLeast - If NewDepth is greater than this node's
423 /// depth value, set it to be the new depth value. This also
424 /// recursively marks successor nodes dirty.
425 void setDepthToAtLeast(unsigned NewDepth);
427 /// setDepthToAtLeast - If NewDepth is greater than this node's
428 /// depth value, set it to be the new height value. This also
429 /// recursively marks predecessor nodes dirty.
430 void setHeightToAtLeast(unsigned NewHeight);
432 /// setDepthDirty - Set a flag in this node to indicate that its
433 /// stored Depth value will require recomputation the next time
434 /// getDepth() is called.
435 void setDepthDirty();
437 /// setHeightDirty - Set a flag in this node to indicate that its
438 /// stored Height value will require recomputation the next time
439 /// getHeight() is called.
440 void setHeightDirty();
442 /// isPred - Test if node N is a predecessor of this node.
443 bool isPred(SUnit *N) {
444 for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
445 if (Preds[i].getSUnit() == N)
450 /// isSucc - Test if node N is a successor of this node.
451 bool isSucc(SUnit *N) {
452 for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
453 if (Succs[i].getSUnit() == N)
458 bool isTopReady() const {
459 return NumPredsLeft == 0;
461 bool isBottomReady() const {
462 return NumSuccsLeft == 0;
465 /// \brief Order this node's predecessor edges such that the critical path
466 /// edge occurs first.
467 void biasCriticalPath();
469 void dump(const ScheduleDAG *G) const;
470 void dumpAll(const ScheduleDAG *G) const;
471 void print(raw_ostream &O, const ScheduleDAG *G) const;
475 void ComputeHeight();
478 //===--------------------------------------------------------------------===//
479 /// SchedulingPriorityQueue - This interface is used to plug different
480 /// priorities computation algorithms into the list scheduler. It implements
481 /// the interface of a standard priority queue, where nodes are inserted in
482 /// arbitrary order and returned in priority order. The computation of the
483 /// priority and the representation of the queue are totally up to the
484 /// implementation to decide.
486 class SchedulingPriorityQueue {
487 virtual void anchor();
491 SchedulingPriorityQueue(bool rf = false):
492 CurCycle(0), HasReadyFilter(rf) {}
493 virtual ~SchedulingPriorityQueue() {}
495 virtual bool isBottomUp() const = 0;
497 virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
498 virtual void addNode(const SUnit *SU) = 0;
499 virtual void updateNode(const SUnit *SU) = 0;
500 virtual void releaseState() = 0;
502 virtual bool empty() const = 0;
504 bool hasReadyFilter() const { return HasReadyFilter; }
506 virtual bool tracksRegPressure() const { return false; }
508 virtual bool isReady(SUnit *) const {
509 assert(!HasReadyFilter && "The ready filter must override isReady()");
512 virtual void push(SUnit *U) = 0;
514 void push_all(const std::vector<SUnit *> &Nodes) {
515 for (std::vector<SUnit *>::const_iterator I = Nodes.begin(),
516 E = Nodes.end(); I != E; ++I)
520 virtual SUnit *pop() = 0;
522 virtual void remove(SUnit *SU) = 0;
524 virtual void dump(ScheduleDAG *) const {}
526 /// scheduledNode - As each node is scheduled, this method is invoked. This
527 /// allows the priority function to adjust the priority of related
528 /// unscheduled nodes, for example.
530 virtual void scheduledNode(SUnit *) {}
532 virtual void unscheduledNode(SUnit *) {}
534 void setCurCycle(unsigned Cycle) {
538 unsigned getCurCycle() const {
545 const TargetMachine &TM; // Target processor
546 const TargetInstrInfo *TII; // Target instruction information
547 const TargetRegisterInfo *TRI; // Target processor register info
548 MachineFunction &MF; // Machine function
549 MachineRegisterInfo &MRI; // Virtual/real register map
550 std::vector<SUnit> SUnits; // The scheduling units.
551 SUnit EntrySU; // Special node for the region entry.
552 SUnit ExitSU; // Special node for the region exit.
555 static const bool StressSched = false;
560 explicit ScheduleDAG(MachineFunction &mf);
562 virtual ~ScheduleDAG();
564 /// clearDAG - clear the DAG state (between regions).
567 /// getInstrDesc - Return the MCInstrDesc of this SUnit.
568 /// Return NULL for SDNodes without a machine opcode.
569 const MCInstrDesc *getInstrDesc(const SUnit *SU) const {
570 if (SU->isInstr()) return &SU->getInstr()->getDesc();
571 return getNodeDesc(SU->getNode());
574 /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
577 virtual void viewGraph(const Twine &Name, const Twine &Title);
578 virtual void viewGraph();
580 virtual void dumpNode(const SUnit *SU) const = 0;
582 /// getGraphNodeLabel - Return a label for an SUnit node in a visualization
583 /// of the ScheduleDAG.
584 virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0;
586 /// getDAGLabel - Return a label for the region of code covered by the DAG.
587 virtual std::string getDAGName() const = 0;
589 /// addCustomGraphFeatures - Add custom features for a visualization of
591 virtual void addCustomGraphFeatures(GraphWriter<ScheduleDAG*> &) const {}
594 /// VerifyScheduledDAG - Verify that all SUnits were scheduled and that
595 /// their state is consistent. Return the number of scheduled SUnits.
596 unsigned VerifyScheduledDAG(bool isBottomUp);
600 // Return the MCInstrDesc of this SDNode or NULL.
601 const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
604 class SUnitIterator : public std::iterator<std::forward_iterator_tag,
609 SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
611 bool operator==(const SUnitIterator& x) const {
612 return Operand == x.Operand;
614 bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
616 const SUnitIterator &operator=(const SUnitIterator &I) {
617 assert(I.Node==Node && "Cannot assign iterators to two different nodes!");
622 pointer operator*() const {
623 return Node->Preds[Operand].getSUnit();
625 pointer operator->() const { return operator*(); }
627 SUnitIterator& operator++() { // Preincrement
631 SUnitIterator operator++(int) { // Postincrement
632 SUnitIterator tmp = *this; ++*this; return tmp;
635 static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
636 static SUnitIterator end (SUnit *N) {
637 return SUnitIterator(N, (unsigned)N->Preds.size());
640 unsigned getOperand() const { return Operand; }
641 const SUnit *getNode() const { return Node; }
642 /// isCtrlDep - Test if this is not an SDep::Data dependence.
643 bool isCtrlDep() const {
644 return getSDep().isCtrl();
646 bool isArtificialDep() const {
647 return getSDep().isArtificial();
649 const SDep &getSDep() const {
650 return Node->Preds[Operand];
654 template <> struct GraphTraits<SUnit*> {
655 typedef SUnit NodeType;
656 typedef SUnitIterator ChildIteratorType;
657 static inline NodeType *getEntryNode(SUnit *N) { return N; }
658 static inline ChildIteratorType child_begin(NodeType *N) {
659 return SUnitIterator::begin(N);
661 static inline ChildIteratorType child_end(NodeType *N) {
662 return SUnitIterator::end(N);
666 template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
667 typedef std::vector<SUnit>::iterator nodes_iterator;
668 static nodes_iterator nodes_begin(ScheduleDAG *G) {
669 return G->SUnits.begin();
671 static nodes_iterator nodes_end(ScheduleDAG *G) {
672 return G->SUnits.end();
676 /// ScheduleDAGTopologicalSort is a class that computes a topological
677 /// ordering for SUnits and provides methods for dynamically updating
678 /// the ordering as new edges are added.
680 /// This allows a very fast implementation of IsReachable, for example.
682 class ScheduleDAGTopologicalSort {
683 /// SUnits - A reference to the ScheduleDAG's SUnits.
684 std::vector<SUnit> &SUnits;
687 /// Index2Node - Maps topological index to the node number.
688 std::vector<int> Index2Node;
689 /// Node2Index - Maps the node number to its topological index.
690 std::vector<int> Node2Index;
691 /// Visited - a set of nodes visited during a DFS traversal.
694 /// DFS - make a DFS traversal and mark all nodes affected by the
695 /// edge insertion. These nodes will later get new topological indexes
696 /// by means of the Shift method.
697 void DFS(const SUnit *SU, int UpperBound, bool& HasLoop);
699 /// Shift - reassign topological indexes for the nodes in the DAG
700 /// to preserve the topological ordering.
701 void Shift(BitVector& Visited, int LowerBound, int UpperBound);
703 /// Allocate - assign the topological index to the node n.
704 void Allocate(int n, int index);
707 ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, SUnit *ExitSU);
709 /// InitDAGTopologicalSorting - create the initial topological
710 /// ordering from the DAG to be scheduled.
711 void InitDAGTopologicalSorting();
713 /// IsReachable - Checks if SU is reachable from TargetSU.
714 bool IsReachable(const SUnit *SU, const SUnit *TargetSU);
716 /// WillCreateCycle - Return true if addPred(TargetSU, SU) creates a cycle.
717 bool WillCreateCycle(SUnit *TargetSU, SUnit *SU);
719 /// AddPred - Updates the topological ordering to accommodate an edge
720 /// to be added from SUnit X to SUnit Y.
721 void AddPred(SUnit *Y, SUnit *X);
723 /// RemovePred - Updates the topological ordering to accommodate an
724 /// an edge to be removed from the specified node N from the predecessors
725 /// of the current node M.
726 void RemovePred(SUnit *M, SUnit *N);
728 typedef std::vector<int>::iterator iterator;
729 typedef std::vector<int>::const_iterator const_iterator;
730 iterator begin() { return Index2Node.begin(); }
731 const_iterator begin() const { return Index2Node.begin(); }
732 iterator end() { return Index2Node.end(); }
733 const_iterator end() const { return Index2Node.end(); }
735 typedef std::vector<int>::reverse_iterator reverse_iterator;
736 typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
737 reverse_iterator rbegin() { return Index2Node.rbegin(); }
738 const_reverse_iterator rbegin() const { return Index2Node.rbegin(); }
739 reverse_iterator rend() { return Index2Node.rend(); }
740 const_reverse_iterator rend() const { return Index2Node.rend(); }