Home | History | Annotate | Download | only in CodeGen
      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
    754