LLVM API Documentation

ScheduleDAG.h
Go to the documentation of this file.
00001 //===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the ScheduleDAG class, which is used as the common
00011 // base class for instruction schedulers. This encapsulates the scheduling DAG,
00012 // which is shared between SelectionDAG and MachineInstr scheduling.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #ifndef LLVM_CODEGEN_SCHEDULEDAG_H
00017 #define LLVM_CODEGEN_SCHEDULEDAG_H
00018 
00019 #include "llvm/ADT/BitVector.h"
00020 #include "llvm/ADT/GraphTraits.h"
00021 #include "llvm/ADT/PointerIntPair.h"
00022 #include "llvm/ADT/SmallVector.h"
00023 #include "llvm/CodeGen/MachineInstr.h"
00024 #include "llvm/Target/TargetLowering.h"
00025 
00026 namespace llvm {
00027   class AliasAnalysis;
00028   class SUnit;
00029   class MachineConstantPool;
00030   class MachineFunction;
00031   class MachineRegisterInfo;
00032   class MachineInstr;
00033   struct MCSchedClassDesc;
00034   class TargetRegisterInfo;
00035   class ScheduleDAG;
00036   class SDNode;
00037   class TargetInstrInfo;
00038   class MCInstrDesc;
00039   class TargetMachine;
00040   class TargetRegisterClass;
00041   template<class Graph> class GraphWriter;
00042 
00043   /// SDep - Scheduling dependency. This represents one direction of an
00044   /// edge in the scheduling DAG.
00045   class SDep {
00046   public:
00047     /// Kind - These are the different kinds of scheduling dependencies.
00048     enum Kind {
00049       Data,        ///< Regular data dependence (aka true-dependence).
00050       Anti,        ///< A register anti-dependedence (aka WAR).
00051       Output,      ///< A register output-dependence (aka WAW).
00052       Order        ///< Any other ordering dependency.
00053     };
00054 
00055     // Strong dependencies must be respected by the scheduler. Artificial
00056     // dependencies may be removed only if they are redundant with another
00057     // strong depedence.
00058     //
00059     // Weak dependencies may be violated by the scheduling strategy, but only if
00060     // the strategy can prove it is correct to do so.
00061     //
00062     // Strong OrderKinds must occur before "Weak".
00063     // Weak OrderKinds must occur after "Weak".
00064     enum OrderKind {
00065       Barrier,      ///< An unknown scheduling barrier.
00066       MayAliasMem,  ///< Nonvolatile load/Store instructions that may alias.
00067       MustAliasMem, ///< Nonvolatile load/Store instructions that must alias.
00068       Artificial,   ///< Arbitrary strong DAG edge (no real dependence).
00069       Weak,         ///< Arbitrary weak DAG edge.
00070       Cluster       ///< Weak DAG edge linking a chain of clustered instrs.
00071     };
00072 
00073   private:
00074     /// Dep - A pointer to the depending/depended-on SUnit, and an enum
00075     /// indicating the kind of the dependency.
00076     PointerIntPair<SUnit *, 2, Kind> Dep;
00077 
00078     /// Contents - A union discriminated by the dependence kind.
00079     union {
00080       /// Reg - For Data, Anti, and Output dependencies, the associated
00081       /// register. For Data dependencies that don't currently have a register
00082       /// assigned, this is set to zero.
00083       unsigned Reg;
00084 
00085       /// Order - Additional information about Order dependencies.
00086       unsigned OrdKind; // enum OrderKind
00087     } Contents;
00088 
00089     /// Latency - The time associated with this edge. Often this is just
00090     /// the value of the Latency field of the predecessor, however advanced
00091     /// models may provide additional information about specific edges.
00092     unsigned Latency;
00093 
00094   public:
00095     /// SDep - Construct a null SDep. This is only for use by container
00096     /// classes which require default constructors. SUnits may not
00097     /// have null SDep edges.
00098     SDep() : Dep(nullptr, Data) {}
00099 
00100     /// SDep - Construct an SDep with the specified values.
00101     SDep(SUnit *S, Kind kind, unsigned Reg)
00102       : Dep(S, kind), Contents() {
00103       switch (kind) {
00104       default:
00105         llvm_unreachable("Reg given for non-register dependence!");
00106       case Anti:
00107       case Output:
00108         assert(Reg != 0 &&
00109                "SDep::Anti and SDep::Output must use a non-zero Reg!");
00110         Contents.Reg = Reg;
00111         Latency = 0;
00112         break;
00113       case Data:
00114         Contents.Reg = Reg;
00115         Latency = 1;
00116         break;
00117       }
00118     }
00119     SDep(SUnit *S, OrderKind kind)
00120       : Dep(S, Order), Contents(), Latency(0) {
00121       Contents.OrdKind = kind;
00122     }
00123 
00124     /// Return true if the specified SDep is equivalent except for latency.
00125     bool overlaps(const SDep &Other) const {
00126       if (Dep != Other.Dep) return false;
00127       switch (Dep.getInt()) {
00128       case Data:
00129       case Anti:
00130       case Output:
00131         return Contents.Reg == Other.Contents.Reg;
00132       case Order:
00133         return Contents.OrdKind == Other.Contents.OrdKind;
00134       }
00135       llvm_unreachable("Invalid dependency kind!");
00136     }
00137 
00138     bool operator==(const SDep &Other) const {
00139       return overlaps(Other) && Latency == Other.Latency;
00140     }
00141 
00142     bool operator!=(const SDep &Other) const {
00143       return !operator==(Other);
00144     }
00145 
00146     /// getLatency - Return the latency value for this edge, which roughly
00147     /// means the minimum number of cycles that must elapse between the
00148     /// predecessor and the successor, given that they have this edge
00149     /// between them.
00150     unsigned getLatency() const {
00151       return Latency;
00152     }
00153 
00154     /// setLatency - Set the latency for this edge.
00155     void setLatency(unsigned Lat) {
00156       Latency = Lat;
00157     }
00158 
00159     //// getSUnit - Return the SUnit to which this edge points.
00160     SUnit *getSUnit() const {
00161       return Dep.getPointer();
00162     }
00163 
00164     //// setSUnit - Assign the SUnit to which this edge points.
00165     void setSUnit(SUnit *SU) {
00166       Dep.setPointer(SU);
00167     }
00168 
00169     /// getKind - Return an enum value representing the kind of the dependence.
00170     Kind getKind() const {
00171       return Dep.getInt();
00172     }
00173 
00174     /// isCtrl - Shorthand for getKind() != SDep::Data.
00175     bool isCtrl() const {
00176       return getKind() != Data;
00177     }
00178 
00179     /// isNormalMemory - Test if this is an Order dependence between two
00180     /// memory accesses where both sides of the dependence access memory
00181     /// in non-volatile and fully modeled ways.
00182     bool isNormalMemory() const {
00183       return getKind() == Order && (Contents.OrdKind == MayAliasMem
00184                                     || Contents.OrdKind == MustAliasMem);
00185     }
00186 
00187     /// isBarrier - Test if this is an Order dependence that is marked
00188     /// as a barrier.
00189     bool isBarrier() const {
00190       return getKind() == Order && Contents.OrdKind == Barrier;
00191     }
00192 
00193     /// isMustAlias - Test if this is an Order dependence that is marked
00194     /// as "must alias", meaning that the SUnits at either end of the edge
00195     /// have a memory dependence on a known memory location.
00196     bool isMustAlias() const {
00197       return getKind() == Order && Contents.OrdKind == MustAliasMem;
00198     }
00199 
00200     /// isWeak - Test if this a weak dependence. Weak dependencies are
00201     /// considered DAG edges for height computation and other heuristics, but do
00202     /// not force ordering. Breaking a weak edge may require the scheduler to
00203     /// compensate, for example by inserting a copy.
00204     bool isWeak() const {
00205       return getKind() == Order && Contents.OrdKind >= Weak;
00206     }
00207 
00208     /// isArtificial - Test if this is an Order dependence that is marked
00209     /// as "artificial", meaning it isn't necessary for correctness.
00210     bool isArtificial() const {
00211       return getKind() == Order && Contents.OrdKind == Artificial;
00212     }
00213 
00214     /// isCluster - Test if this is an Order dependence that is marked
00215     /// as "cluster", meaning it is artificial and wants to be adjacent.
00216     bool isCluster() const {
00217       return getKind() == Order && Contents.OrdKind == Cluster;
00218     }
00219 
00220     /// isAssignedRegDep - Test if this is a Data dependence that is
00221     /// associated with a register.
00222     bool isAssignedRegDep() const {
00223       return getKind() == Data && Contents.Reg != 0;
00224     }
00225 
00226     /// getReg - Return the register associated with this edge. This is
00227     /// only valid on Data, Anti, and Output edges. On Data edges, this
00228     /// value may be zero, meaning there is no associated register.
00229     unsigned getReg() const {
00230       assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
00231              "getReg called on non-register dependence edge!");
00232       return Contents.Reg;
00233     }
00234 
00235     /// setReg - Assign the associated register for this edge. This is
00236     /// only valid on Data, Anti, and Output edges. On Anti and Output
00237     /// edges, this value must not be zero. On Data edges, the value may
00238     /// be zero, which would mean that no specific register is associated
00239     /// with this edge.
00240     void setReg(unsigned Reg) {
00241       assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
00242              "setReg called on non-register dependence edge!");
00243       assert((getKind() != Anti || Reg != 0) &&
00244              "SDep::Anti edge cannot use the zero register!");
00245       assert((getKind() != Output || Reg != 0) &&
00246              "SDep::Output edge cannot use the zero register!");
00247       Contents.Reg = Reg;
00248     }
00249   };
00250 
00251   template <>
00252   struct isPodLike<SDep> { static const bool value = true; };
00253 
00254   /// SUnit - Scheduling unit. This is a node in the scheduling DAG.
00255   class SUnit {
00256   private:
00257     enum : unsigned { BoundaryID = ~0u };
00258 
00259     SDNode *Node;                       // Representative node.
00260     MachineInstr *Instr;                // Alternatively, a MachineInstr.
00261   public:
00262     SUnit *OrigNode;                    // If not this, the node from which
00263                                         // this node was cloned.
00264                                         // (SD scheduling only)
00265 
00266     const MCSchedClassDesc *SchedClass; // NULL or resolved SchedClass.
00267 
00268     // Preds/Succs - The SUnits before/after us in the graph.
00269     SmallVector<SDep, 4> Preds;  // All sunit predecessors.
00270     SmallVector<SDep, 4> Succs;  // All sunit successors.
00271 
00272     typedef SmallVectorImpl<SDep>::iterator pred_iterator;
00273     typedef SmallVectorImpl<SDep>::iterator succ_iterator;
00274     typedef SmallVectorImpl<SDep>::const_iterator const_pred_iterator;
00275     typedef SmallVectorImpl<SDep>::const_iterator const_succ_iterator;
00276 
00277     unsigned NodeNum;                   // Entry # of node in the node vector.
00278     unsigned NodeQueueId;               // Queue id of node.
00279     unsigned NumPreds;                  // # of SDep::Data preds.
00280     unsigned NumSuccs;                  // # of SDep::Data sucss.
00281     unsigned NumPredsLeft;              // # of preds not scheduled.
00282     unsigned NumSuccsLeft;              // # of succs not scheduled.
00283     unsigned WeakPredsLeft;             // # of weak preds not scheduled.
00284     unsigned WeakSuccsLeft;             // # of weak succs not scheduled.
00285     unsigned short NumRegDefsLeft;      // # of reg defs with no scheduled use.
00286     unsigned short Latency;             // Node latency.
00287     bool isVRegCycle      : 1;          // May use and def the same vreg.
00288     bool isCall           : 1;          // Is a function call.
00289     bool isCallOp         : 1;          // Is a function call operand.
00290     bool isTwoAddress     : 1;          // Is a two-address instruction.
00291     bool isCommutable     : 1;          // Is a commutable instruction.
00292     bool hasPhysRegUses   : 1;          // Has physreg uses.
00293     bool hasPhysRegDefs   : 1;          // Has physreg defs that are being used.
00294     bool hasPhysRegClobbers : 1;        // Has any physreg defs, used or not.
00295     bool isPending        : 1;          // True once pending.
00296     bool isAvailable      : 1;          // True once available.
00297     bool isScheduled      : 1;          // True once scheduled.
00298     bool isScheduleHigh   : 1;          // True if preferable to schedule high.
00299     bool isScheduleLow    : 1;          // True if preferable to schedule low.
00300     bool isCloned         : 1;          // True if this node has been cloned.
00301     bool isUnbuffered     : 1;          // Uses an unbuffered resource.
00302     bool hasReservedResource : 1;       // Uses a reserved resource.
00303     Sched::Preference SchedulingPref;   // Scheduling preference.
00304 
00305   private:
00306     bool isDepthCurrent   : 1;          // True if Depth is current.
00307     bool isHeightCurrent  : 1;          // True if Height is current.
00308     unsigned Depth;                     // Node depth.
00309     unsigned Height;                    // Node height.
00310   public:
00311     unsigned TopReadyCycle; // Cycle relative to start when node is ready.
00312     unsigned BotReadyCycle; // Cycle relative to end when node is ready.
00313 
00314     const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
00315     const TargetRegisterClass *CopySrcRC;
00316 
00317     /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
00318     /// an SDNode and any nodes flagged to it.
00319     SUnit(SDNode *node, unsigned nodenum)
00320       : Node(node), Instr(nullptr), OrigNode(nullptr), SchedClass(nullptr),
00321         NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0),
00322         NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
00323         NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
00324         isCallOp(false), isTwoAddress(false), isCommutable(false),
00325         hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
00326         isPending(false), isAvailable(false), isScheduled(false),
00327         isScheduleHigh(false), isScheduleLow(false), isCloned(false),
00328         isUnbuffered(false), hasReservedResource(false),
00329         SchedulingPref(Sched::None), isDepthCurrent(false),
00330         isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
00331         BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}
00332 
00333     /// SUnit - Construct an SUnit for post-regalloc scheduling to represent
00334     /// a MachineInstr.
00335     SUnit(MachineInstr *instr, unsigned nodenum)
00336       : Node(nullptr), Instr(instr), OrigNode(nullptr), SchedClass(nullptr),
00337         NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0),
00338         NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
00339         NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
00340         isCallOp(false), isTwoAddress(false), isCommutable(false),
00341         hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
00342         isPending(false), isAvailable(false), isScheduled(false),
00343         isScheduleHigh(false), isScheduleLow(false), isCloned(false),
00344         isUnbuffered(false), hasReservedResource(false),
00345         SchedulingPref(Sched::None), isDepthCurrent(false),
00346         isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
00347         BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}
00348 
00349     /// SUnit - Construct a placeholder SUnit.
00350     SUnit()
00351       : Node(nullptr), Instr(nullptr), OrigNode(nullptr), SchedClass(nullptr),
00352         NodeNum(BoundaryID), NodeQueueId(0), NumPreds(0), NumSuccs(0),
00353         NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
00354         NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
00355         isCallOp(false), isTwoAddress(false), isCommutable(false),
00356         hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
00357         isPending(false), isAvailable(false), isScheduled(false),
00358         isScheduleHigh(false), isScheduleLow(false), isCloned(false),
00359         isUnbuffered(false), hasReservedResource(false),
00360         SchedulingPref(Sched::None), isDepthCurrent(false),
00361         isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
00362         BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}
00363 
00364     /// \brief Boundary nodes are placeholders for the boundary of the
00365     /// scheduling region.
00366     ///
00367     /// BoundaryNodes can have DAG edges, including Data edges, but they do not
00368     /// correspond to schedulable entities (e.g. instructions) and do not have a
00369     /// valid ID. Consequently, always check for boundary nodes before accessing
00370     /// an assoicative data structure keyed on node ID.
00371     bool isBoundaryNode() const { return NodeNum == BoundaryID; };
00372 
00373     /// setNode - Assign the representative SDNode for this SUnit.
00374     /// This may be used during pre-regalloc scheduling.
00375     void setNode(SDNode *N) {
00376       assert(!Instr && "Setting SDNode of SUnit with MachineInstr!");
00377       Node = N;
00378     }
00379 
00380     /// getNode - Return the representative SDNode for this SUnit.
00381     /// This may be used during pre-regalloc scheduling.
00382     SDNode *getNode() const {
00383       assert(!Instr && "Reading SDNode of SUnit with MachineInstr!");
00384       return Node;
00385     }
00386 
00387     /// isInstr - Return true if this SUnit refers to a machine instruction as
00388     /// opposed to an SDNode.
00389     bool isInstr() const { return Instr; }
00390 
00391     /// setInstr - Assign the instruction for the SUnit.
00392     /// This may be used during post-regalloc scheduling.
00393     void setInstr(MachineInstr *MI) {
00394       assert(!Node && "Setting MachineInstr of SUnit with SDNode!");
00395       Instr = MI;
00396     }
00397 
00398     /// getInstr - Return the representative MachineInstr for this SUnit.
00399     /// This may be used during post-regalloc scheduling.
00400     MachineInstr *getInstr() const {
00401       assert(!Node && "Reading MachineInstr of SUnit with SDNode!");
00402       return Instr;
00403     }
00404 
00405     /// addPred - This adds the specified edge as a pred of the current node if
00406     /// not already.  It also adds the current node as a successor of the
00407     /// specified node.
00408     bool addPred(const SDep &D, bool Required = true);
00409 
00410     /// removePred - This removes the specified edge as a pred of the current
00411     /// node if it exists.  It also removes the current node as a successor of
00412     /// the specified node.
00413     void removePred(const SDep &D);
00414 
00415     /// getDepth - Return the depth of this node, which is the length of the
00416     /// maximum path up to any node which has no predecessors.
00417     unsigned getDepth() const {
00418       if (!isDepthCurrent)
00419         const_cast<SUnit *>(this)->ComputeDepth();
00420       return Depth;
00421     }
00422 
00423     /// getHeight - Return the height of this node, which is the length of the
00424     /// maximum path down to any node which has no successors.
00425     unsigned getHeight() const {
00426       if (!isHeightCurrent)
00427         const_cast<SUnit *>(this)->ComputeHeight();
00428       return Height;
00429     }
00430 
00431     /// setDepthToAtLeast - If NewDepth is greater than this node's
00432     /// depth value, set it to be the new depth value. This also
00433     /// recursively marks successor nodes dirty.
00434     void setDepthToAtLeast(unsigned NewDepth);
00435 
00436     /// setDepthToAtLeast - If NewDepth is greater than this node's
00437     /// depth value, set it to be the new height value. This also
00438     /// recursively marks predecessor nodes dirty.
00439     void setHeightToAtLeast(unsigned NewHeight);
00440 
00441     /// setDepthDirty - Set a flag in this node to indicate that its
00442     /// stored Depth value will require recomputation the next time
00443     /// getDepth() is called.
00444     void setDepthDirty();
00445 
00446     /// setHeightDirty - Set a flag in this node to indicate that its
00447     /// stored Height value will require recomputation the next time
00448     /// getHeight() is called.
00449     void setHeightDirty();
00450 
00451     /// isPred - Test if node N is a predecessor of this node.
00452     bool isPred(SUnit *N) {
00453       for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
00454         if (Preds[i].getSUnit() == N)
00455           return true;
00456       return false;
00457     }
00458 
00459     /// isSucc - Test if node N is a successor of this node.
00460     bool isSucc(SUnit *N) {
00461       for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
00462         if (Succs[i].getSUnit() == N)
00463           return true;
00464       return false;
00465     }
00466 
00467     bool isTopReady() const {
00468       return NumPredsLeft == 0;
00469     }
00470     bool isBottomReady() const {
00471       return NumSuccsLeft == 0;
00472     }
00473 
00474     /// \brief Order this node's predecessor edges such that the critical path
00475     /// edge occurs first.
00476     void biasCriticalPath();
00477 
00478     void dump(const ScheduleDAG *G) const;
00479     void dumpAll(const ScheduleDAG *G) const;
00480     void print(raw_ostream &O, const ScheduleDAG *G) const;
00481 
00482   private:
00483     void ComputeDepth();
00484     void ComputeHeight();
00485   };
00486 
00487   //===--------------------------------------------------------------------===//
00488   /// SchedulingPriorityQueue - This interface is used to plug different
00489   /// priorities computation algorithms into the list scheduler. It implements
00490   /// the interface of a standard priority queue, where nodes are inserted in
00491   /// arbitrary order and returned in priority order.  The computation of the
00492   /// priority and the representation of the queue are totally up to the
00493   /// implementation to decide.
00494   ///
00495   class SchedulingPriorityQueue {
00496     virtual void anchor();
00497     unsigned CurCycle;
00498     bool HasReadyFilter;
00499   public:
00500     SchedulingPriorityQueue(bool rf = false):
00501       CurCycle(0), HasReadyFilter(rf) {}
00502     virtual ~SchedulingPriorityQueue() {}
00503 
00504     virtual bool isBottomUp() const = 0;
00505 
00506     virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
00507     virtual void addNode(const SUnit *SU) = 0;
00508     virtual void updateNode(const SUnit *SU) = 0;
00509     virtual void releaseState() = 0;
00510 
00511     virtual bool empty() const = 0;
00512 
00513     bool hasReadyFilter() const { return HasReadyFilter; }
00514 
00515     virtual bool tracksRegPressure() const { return false; }
00516 
00517     virtual bool isReady(SUnit *) const {
00518       assert(!HasReadyFilter && "The ready filter must override isReady()");
00519       return true;
00520     }
00521     virtual void push(SUnit *U) = 0;
00522 
00523     void push_all(const std::vector<SUnit *> &Nodes) {
00524       for (std::vector<SUnit *>::const_iterator I = Nodes.begin(),
00525            E = Nodes.end(); I != E; ++I)
00526         push(*I);
00527     }
00528 
00529     virtual SUnit *pop() = 0;
00530 
00531     virtual void remove(SUnit *SU) = 0;
00532 
00533     virtual void dump(ScheduleDAG *) const {}
00534 
00535     /// scheduledNode - As each node is scheduled, this method is invoked.  This
00536     /// allows the priority function to adjust the priority of related
00537     /// unscheduled nodes, for example.
00538     ///
00539     virtual void scheduledNode(SUnit *) {}
00540 
00541     virtual void unscheduledNode(SUnit *) {}
00542 
00543     void setCurCycle(unsigned Cycle) {
00544       CurCycle = Cycle;
00545     }
00546 
00547     unsigned getCurCycle() const {
00548       return CurCycle;
00549     }
00550   };
00551 
00552   class ScheduleDAG {
00553   public:
00554     const TargetMachine &TM;              // Target processor
00555     const TargetInstrInfo *TII;           // Target instruction information
00556     const TargetRegisterInfo *TRI;        // Target processor register info
00557     MachineFunction &MF;                  // Machine function
00558     MachineRegisterInfo &MRI;             // Virtual/real register map
00559     std::vector<SUnit> SUnits;            // The scheduling units.
00560     SUnit EntrySU;                        // Special node for the region entry.
00561     SUnit ExitSU;                         // Special node for the region exit.
00562 
00563 #ifdef NDEBUG
00564     static const bool StressSched = false;
00565 #else
00566     bool StressSched;
00567 #endif
00568 
00569     explicit ScheduleDAG(MachineFunction &mf);
00570 
00571     virtual ~ScheduleDAG();
00572 
00573     /// clearDAG - clear the DAG state (between regions).
00574     void clearDAG();
00575 
00576     /// getInstrDesc - Return the MCInstrDesc of this SUnit.
00577     /// Return NULL for SDNodes without a machine opcode.
00578     const MCInstrDesc *getInstrDesc(const SUnit *SU) const {
00579       if (SU->isInstr()) return &SU->getInstr()->getDesc();
00580       return getNodeDesc(SU->getNode());
00581     }
00582 
00583     /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
00584     /// using 'dot'.
00585     ///
00586     virtual void viewGraph(const Twine &Name, const Twine &Title);
00587     virtual void viewGraph();
00588 
00589     virtual void dumpNode(const SUnit *SU) const = 0;
00590 
00591     /// getGraphNodeLabel - Return a label for an SUnit node in a visualization
00592     /// of the ScheduleDAG.
00593     virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0;
00594 
00595     /// getDAGLabel - Return a label for the region of code covered by the DAG.
00596     virtual std::string getDAGName() const = 0;
00597 
00598     /// addCustomGraphFeatures - Add custom features for a visualization of
00599     /// the ScheduleDAG.
00600     virtual void addCustomGraphFeatures(GraphWriter<ScheduleDAG*> &) const {}
00601 
00602 #ifndef NDEBUG
00603     /// VerifyScheduledDAG - Verify that all SUnits were scheduled and that
00604     /// their state is consistent. Return the number of scheduled SUnits.
00605     unsigned VerifyScheduledDAG(bool isBottomUp);
00606 #endif
00607 
00608   private:
00609     // Return the MCInstrDesc of this SDNode or NULL.
00610     const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
00611   };
00612 
00613   class SUnitIterator : public std::iterator<std::forward_iterator_tag,
00614                                              SUnit, ptrdiff_t> {
00615     SUnit *Node;
00616     unsigned Operand;
00617 
00618     SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
00619   public:
00620     bool operator==(const SUnitIterator& x) const {
00621       return Operand == x.Operand;
00622     }
00623     bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
00624 
00625     const SUnitIterator &operator=(const SUnitIterator &I) {
00626       assert(I.Node==Node && "Cannot assign iterators to two different nodes!");
00627       Operand = I.Operand;
00628       return *this;
00629     }
00630 
00631     pointer operator*() const {
00632       return Node->Preds[Operand].getSUnit();
00633     }
00634     pointer operator->() const { return operator*(); }
00635 
00636     SUnitIterator& operator++() {                // Preincrement
00637       ++Operand;
00638       return *this;
00639     }
00640     SUnitIterator operator++(int) { // Postincrement
00641       SUnitIterator tmp = *this; ++*this; return tmp;
00642     }
00643 
00644     static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
00645     static SUnitIterator end  (SUnit *N) {
00646       return SUnitIterator(N, (unsigned)N->Preds.size());
00647     }
00648 
00649     unsigned getOperand() const { return Operand; }
00650     const SUnit *getNode() const { return Node; }
00651     /// isCtrlDep - Test if this is not an SDep::Data dependence.
00652     bool isCtrlDep() const {
00653       return getSDep().isCtrl();
00654     }
00655     bool isArtificialDep() const {
00656       return getSDep().isArtificial();
00657     }
00658     const SDep &getSDep() const {
00659       return Node->Preds[Operand];
00660     }
00661   };
00662 
00663   template <> struct GraphTraits<SUnit*> {
00664     typedef SUnit NodeType;
00665     typedef SUnitIterator ChildIteratorType;
00666     static inline NodeType *getEntryNode(SUnit *N) { return N; }
00667     static inline ChildIteratorType child_begin(NodeType *N) {
00668       return SUnitIterator::begin(N);
00669     }
00670     static inline ChildIteratorType child_end(NodeType *N) {
00671       return SUnitIterator::end(N);
00672     }
00673   };
00674 
00675   template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
00676     typedef std::vector<SUnit>::iterator nodes_iterator;
00677     static nodes_iterator nodes_begin(ScheduleDAG *G) {
00678       return G->SUnits.begin();
00679     }
00680     static nodes_iterator nodes_end(ScheduleDAG *G) {
00681       return G->SUnits.end();
00682     }
00683   };
00684 
00685   /// ScheduleDAGTopologicalSort is a class that computes a topological
00686   /// ordering for SUnits and provides methods for dynamically updating
00687   /// the ordering as new edges are added.
00688   ///
00689   /// This allows a very fast implementation of IsReachable, for example.
00690   ///
00691   class ScheduleDAGTopologicalSort {
00692     /// SUnits - A reference to the ScheduleDAG's SUnits.
00693     std::vector<SUnit> &SUnits;
00694     SUnit *ExitSU;
00695 
00696     /// Index2Node - Maps topological index to the node number.
00697     std::vector<int> Index2Node;
00698     /// Node2Index - Maps the node number to its topological index.
00699     std::vector<int> Node2Index;
00700     /// Visited - a set of nodes visited during a DFS traversal.
00701     BitVector Visited;
00702 
00703     /// DFS - make a DFS traversal and mark all nodes affected by the
00704     /// edge insertion. These nodes will later get new topological indexes
00705     /// by means of the Shift method.
00706     void DFS(const SUnit *SU, int UpperBound, bool& HasLoop);
00707 
00708     /// Shift - reassign topological indexes for the nodes in the DAG
00709     /// to preserve the topological ordering.
00710     void Shift(BitVector& Visited, int LowerBound, int UpperBound);
00711 
00712     /// Allocate - assign the topological index to the node n.
00713     void Allocate(int n, int index);
00714 
00715   public:
00716     ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, SUnit *ExitSU);
00717 
00718     /// InitDAGTopologicalSorting - create the initial topological
00719     /// ordering from the DAG to be scheduled.
00720     void InitDAGTopologicalSorting();
00721 
00722     /// IsReachable - Checks if SU is reachable from TargetSU.
00723     bool IsReachable(const SUnit *SU, const SUnit *TargetSU);
00724 
00725     /// WillCreateCycle - Return true if addPred(TargetSU, SU) creates a cycle.
00726     bool WillCreateCycle(SUnit *TargetSU, SUnit *SU);
00727 
00728     /// AddPred - Updates the topological ordering to accommodate an edge
00729     /// to be added from SUnit X to SUnit Y.
00730     void AddPred(SUnit *Y, SUnit *X);
00731 
00732     /// RemovePred - Updates the topological ordering to accommodate an
00733     /// an edge to be removed from the specified node N from the predecessors
00734     /// of the current node M.
00735     void RemovePred(SUnit *M, SUnit *N);
00736 
00737     typedef std::vector<int>::iterator iterator;
00738     typedef std::vector<int>::const_iterator const_iterator;
00739     iterator begin() { return Index2Node.begin(); }
00740     const_iterator begin() const { return Index2Node.begin(); }
00741     iterator end() { return Index2Node.end(); }
00742     const_iterator end() const { return Index2Node.end(); }
00743 
00744     typedef std::vector<int>::reverse_iterator reverse_iterator;
00745     typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
00746     reverse_iterator rbegin() { return Index2Node.rbegin(); }
00747     const_reverse_iterator rbegin() const { return Index2Node.rbegin(); }
00748     reverse_iterator rend() { return Index2Node.rend(); }
00749     const_reverse_iterator rend() const { return Index2Node.rend(); }
00750   };
00751 }
00752 
00753 #endif