//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the ScheduleDAG class, which is used as the common
// base class for instruction schedulers. This encapsulates the scheduling DAG,
// which is shared between SelectionDAG and MachineInstr scheduling.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_SCHEDULEDAG_H
#define LLVM_CODEGEN_SCHEDULEDAG_H

#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Target/TargetLowering.h"

namespace llvm {
  class AliasAnalysis;
  class SUnit;
  class MachineConstantPool;
  class MachineFunction;
  class MachineRegisterInfo;
  class MachineInstr;
  struct MCSchedClassDesc;
  class TargetRegisterInfo;
  class ScheduleDAG;
  class SDNode;
  class TargetInstrInfo;
  class MCInstrDesc;
  class TargetMachine;
  class TargetRegisterClass;
  template<class Graph> class GraphWriter;

  /// SDep - Scheduling dependency. This represents one direction of an
  /// edge in the scheduling DAG.
  class SDep {
  public:
    /// Kind - These are the different kinds of scheduling dependencies.
    enum Kind {
      Data,        ///< Regular data dependence (aka true-dependence).
      Anti,        ///< A register anti-dependedence (aka WAR).
      Output,      ///< A register output-dependence (aka WAW).
      Order        ///< Any other ordering dependency.
    };

    // Strong dependencies must be respected by the scheduler. Artificial
    // dependencies may be removed only if they are redundant with another
    // strong depedence.
    //
    // Weak dependencies may be violated by the scheduling strategy, but only if
    // the strategy can prove it is correct to do so.
    //
    // Strong OrderKinds must occur before "Weak".
    // Weak OrderKinds must occur after "Weak".
    enum OrderKind {
      Barrier,      ///< An unknown scheduling barrier.
      MayAliasMem,  ///< Nonvolatile load/Store instructions that may alias.
      MustAliasMem, ///< Nonvolatile load/Store instructions that must alias.
      Artificial,   ///< Arbitrary strong DAG edge (no real dependence).
      Weak,         ///< Arbitrary weak DAG edge.
      Cluster       ///< Weak DAG edge linking a chain of clustered instrs.
    };

  private:
    /// Dep - A pointer to the depending/depended-on SUnit, and an enum
    /// indicating the kind of the dependency.
    PointerIntPair<SUnit *, 2, Kind> Dep;

    /// Contents - A union discriminated by the dependence kind.
    union {
      /// Reg - For Data, Anti, and Output dependencies, the associated
      /// register. For Data dependencies that don't currently have a register
      /// assigned, this is set to zero.
      unsigned Reg;

      /// Order - Additional information about Order dependencies.
      unsigned OrdKind; // enum OrderKind
    } Contents;

    /// Latency - The time associated with this edge. Often this is just
    /// the value of the Latency field of the predecessor, however advanced
    /// models may provide additional information about specific edges.
    unsigned Latency;

  public:
    /// SDep - Construct a null SDep. This is only for use by container
    /// classes which require default constructors. SUnits may not
    /// have null SDep edges.
    SDep() : Dep(nullptr, Data) {}

    /// SDep - Construct an SDep with the specified values.
    SDep(SUnit *S, Kind kind, unsigned Reg)
      : Dep(S, kind), Contents() {
      switch (kind) {
      default:
        llvm_unreachable("Reg given for non-register dependence!");
      case Anti:
      case Output:
        assert(Reg != 0 &&
               "SDep::Anti and SDep::Output must use a non-zero Reg!");
        Contents.Reg = Reg;
        Latency = 0;
        break;
      case Data:
        Contents.Reg = Reg;
        Latency = 1;
        break;
      }
    }
    SDep(SUnit *S, OrderKind kind)
      : Dep(S, Order), Contents(), Latency(0) {
      Contents.OrdKind = kind;
    }

    /// Return true if the specified SDep is equivalent except for latency.
    bool overlaps(const SDep &Other) const {
      if (Dep != Other.Dep) return false;
      switch (Dep.getInt()) {
      case Data:
      case Anti:
      case Output:
        return Contents.Reg == Other.Contents.Reg;
      case Order:
        return Contents.OrdKind == Other.Contents.OrdKind;
      }
      llvm_unreachable("Invalid dependency kind!");
    }

    bool operator==(const SDep &Other) const {
      return overlaps(Other) && Latency == Other.Latency;
    }

    bool operator!=(const SDep &Other) const {
      return !operator==(Other);
    }

    /// getLatency - Return the latency value for this edge, which roughly
    /// means the minimum number of cycles that must elapse between the
    /// predecessor and the successor, given that they have this edge
    /// between them.
    unsigned getLatency() const {
      return Latency;
    }

    /// setLatency - Set the latency for this edge.
    void setLatency(unsigned Lat) {
      Latency = Lat;
    }

    //// getSUnit - Return the SUnit to which this edge points.
    SUnit *getSUnit() const {
      return Dep.getPointer();
    }

    //// setSUnit - Assign the SUnit to which this edge points.
    void setSUnit(SUnit *SU) {
      Dep.setPointer(SU);
    }

    /// getKind - Return an enum value representing the kind of the dependence.
    Kind getKind() const {
      return Dep.getInt();
    }

    /// isCtrl - Shorthand for getKind() != SDep::Data.
    bool isCtrl() const {
      return getKind() != Data;
    }

    /// isNormalMemory - Test if this is an Order dependence between two
    /// memory accesses where both sides of the dependence access memory
    /// in non-volatile and fully modeled ways.
    bool isNormalMemory() const {
      return getKind() == Order && (Contents.OrdKind == MayAliasMem
                                    || Contents.OrdKind == MustAliasMem);
    }

    /// isBarrier - Test if this is an Order dependence that is marked
    /// as a barrier.
    bool isBarrier() const {
      return getKind() == Order && Contents.OrdKind == Barrier;
    }

    /// isMustAlias - Test if this is an Order dependence that is marked
    /// as "must alias", meaning that the SUnits at either end of the edge
    /// have a memory dependence on a known memory location.
    bool isMustAlias() const {
      return getKind() == Order && Contents.OrdKind == MustAliasMem;
    }

    /// isWeak - Test if this a weak dependence. Weak dependencies are
    /// considered DAG edges for height computation and other heuristics, but do
    /// not force ordering. Breaking a weak edge may require the scheduler to
    /// compensate, for example by inserting a copy.
    bool isWeak() const {
      return getKind() == Order && Contents.OrdKind >= Weak;
    }

    /// isArtificial - Test if this is an Order dependence that is marked
    /// as "artificial", meaning it isn't necessary for correctness.
    bool isArtificial() const {
      return getKind() == Order && Contents.OrdKind == Artificial;
    }

    /// isCluster - Test if this is an Order dependence that is marked
    /// as "cluster", meaning it is artificial and wants to be adjacent.
    bool isCluster() const {
      return getKind() == Order && Contents.OrdKind == Cluster;
    }

    /// isAssignedRegDep - Test if this is a Data dependence that is
    /// associated with a register.
    bool isAssignedRegDep() const {
      return getKind() == Data && Contents.Reg != 0;
    }

    /// getReg - Return the register associated with this edge. This is
    /// only valid on Data, Anti, and Output edges. On Data edges, this
    /// value may be zero, meaning there is no associated register.
    unsigned getReg() const {
      assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
             "getReg called on non-register dependence edge!");
      return Contents.Reg;
    }

    /// setReg - Assign the associated register for this edge. This is
    /// only valid on Data, Anti, and Output edges. On Anti and Output
    /// edges, this value must not be zero. On Data edges, the value may
    /// be zero, which would mean that no specific register is associated
    /// with this edge.
    void setReg(unsigned Reg) {
      assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
             "setReg called on non-register dependence edge!");
      assert((getKind() != Anti || Reg != 0) &&
             "SDep::Anti edge cannot use the zero register!");
      assert((getKind() != Output || Reg != 0) &&
             "SDep::Output edge cannot use the zero register!");
      Contents.Reg = Reg;
    }
  };

  template <>
  struct isPodLike<SDep> { static const bool value = true; };

  /// SUnit - Scheduling unit. This is a node in the scheduling DAG.
  class SUnit {
  private:
    enum : unsigned { BoundaryID = ~0u };

    SDNode *Node;                       // Representative node.
    MachineInstr *Instr;                // Alternatively, a MachineInstr.
  public:
    SUnit *OrigNode;                    // If not this, the node from which
                                        // this node was cloned.
                                        // (SD scheduling only)

    const MCSchedClassDesc *SchedClass; // NULL or resolved SchedClass.

    // Preds/Succs - The SUnits before/after us in the graph.
    SmallVector<SDep, 4> Preds;  // All sunit predecessors.
    SmallVector<SDep, 4> Succs;  // All sunit successors.

    typedef SmallVectorImpl<SDep>::iterator pred_iterator;
    typedef SmallVectorImpl<SDep>::iterator succ_iterator;
    typedef SmallVectorImpl<SDep>::const_iterator const_pred_iterator;
    typedef SmallVectorImpl<SDep>::const_iterator const_succ_iterator;

    unsigned NodeNum;                   // Entry # of node in the node vector.
    unsigned NodeQueueId;               // Queue id of node.
    unsigned NumPreds;                  // # of SDep::Data preds.
    unsigned NumSuccs;                  // # of SDep::Data sucss.
    unsigned NumPredsLeft;              // # of preds not scheduled.
    unsigned NumSuccsLeft;              // # of succs not scheduled.
    unsigned WeakPredsLeft;             // # of weak preds not scheduled.
    unsigned WeakSuccsLeft;             // # of weak succs not scheduled.
    unsigned short NumRegDefsLeft;      // # of reg defs with no scheduled use.
    unsigned short Latency;             // Node latency.
    bool isVRegCycle      : 1;          // May use and def the same vreg.
    bool isCall           : 1;          // Is a function call.
    bool isCallOp         : 1;          // Is a function call operand.
    bool isTwoAddress     : 1;          // Is a two-address instruction.
    bool isCommutable     : 1;          // Is a commutable instruction.
    bool hasPhysRegUses   : 1;          // Has physreg uses.
    bool hasPhysRegDefs   : 1;          // Has physreg defs that are being used.
    bool hasPhysRegClobbers : 1;        // Has any physreg defs, used or not.
    bool isPending        : 1;          // True once pending.
    bool isAvailable      : 1;          // True once available.
    bool isScheduled      : 1;          // True once scheduled.
    bool isScheduleHigh   : 1;          // True if preferable to schedule high.
    bool isScheduleLow    : 1;          // True if preferable to schedule low.
    bool isCloned         : 1;          // True if this node has been cloned.
    bool isUnbuffered     : 1;          // Uses an unbuffered resource.
    bool hasReservedResource : 1;       // Uses a reserved resource.
    Sched::Preference SchedulingPref;   // Scheduling preference.

  private:
    bool isDepthCurrent   : 1;          // True if Depth is current.
    bool isHeightCurrent  : 1;          // True if Height is current.
    unsigned Depth;                     // Node depth.
    unsigned Height;                    // Node height.
  public:
    unsigned TopReadyCycle; // Cycle relative to start when node is ready.
    unsigned BotReadyCycle; // Cycle relative to end when node is ready.

    const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
    const TargetRegisterClass *CopySrcRC;

    /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
    /// an SDNode and any nodes flagged to it.
    SUnit(SDNode *node, unsigned nodenum)
      : Node(node), Instr(nullptr), OrigNode(nullptr), SchedClass(nullptr),
        NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0),
        NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
        NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
        isCallOp(false), isTwoAddress(false), isCommutable(false),
        hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
        isPending(false), isAvailable(false), isScheduled(false),
        isScheduleHigh(false), isScheduleLow(false), isCloned(false),
        isUnbuffered(false), hasReservedResource(false),
        SchedulingPref(Sched::None), isDepthCurrent(false),
        isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
        BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}

    /// SUnit - Construct an SUnit for post-regalloc scheduling to represent
    /// a MachineInstr.
    SUnit(MachineInstr *instr, unsigned nodenum)
      : Node(nullptr), Instr(instr), OrigNode(nullptr), SchedClass(nullptr),
        NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0),
        NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
        NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
        isCallOp(false), isTwoAddress(false), isCommutable(false),
        hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
        isPending(false), isAvailable(false), isScheduled(false),
        isScheduleHigh(false), isScheduleLow(false), isCloned(false),
        isUnbuffered(false), hasReservedResource(false),
        SchedulingPref(Sched::None), isDepthCurrent(false),
        isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
        BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}

    /// SUnit - Construct a placeholder SUnit.
    SUnit()
      : Node(nullptr), Instr(nullptr), OrigNode(nullptr), SchedClass(nullptr),
        NodeNum(BoundaryID), NodeQueueId(0), NumPreds(0), NumSuccs(0),
        NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
        NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
        isCallOp(false), isTwoAddress(false), isCommutable(false),
        hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
        isPending(false), isAvailable(false), isScheduled(false),
        isScheduleHigh(false), isScheduleLow(false), isCloned(false),
        isUnbuffered(false), hasReservedResource(false),
        SchedulingPref(Sched::None), isDepthCurrent(false),
        isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
        BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}

    /// \brief Boundary nodes are placeholders for the boundary of the
    /// scheduling region.
    ///
    /// BoundaryNodes can have DAG edges, including Data edges, but they do not
    /// correspond to schedulable entities (e.g. instructions) and do not have a
    /// valid ID. Consequently, always check for boundary nodes before accessing
    /// an assoicative data structure keyed on node ID.
    bool isBoundaryNode() const { return NodeNum == BoundaryID; };

    /// setNode - Assign the representative SDNode for this SUnit.
    /// This may be used during pre-regalloc scheduling.
    void setNode(SDNode *N) {
      assert(!Instr && "Setting SDNode of SUnit with MachineInstr!");
      Node = N;
    }

    /// getNode - Return the representative SDNode for this SUnit.
    /// This may be used during pre-regalloc scheduling.
    SDNode *getNode() const {
      assert(!Instr && "Reading SDNode of SUnit with MachineInstr!");
      return Node;
    }

    /// isInstr - Return true if this SUnit refers to a machine instruction as
    /// opposed to an SDNode.
    bool isInstr() const { return Instr; }

    /// setInstr - Assign the instruction for the SUnit.
    /// This may be used during post-regalloc scheduling.
    void setInstr(MachineInstr *MI) {
      assert(!Node && "Setting MachineInstr of SUnit with SDNode!");
      Instr = MI;
    }

    /// getInstr - Return the representative MachineInstr for this SUnit.
    /// This may be used during post-regalloc scheduling.
    MachineInstr *getInstr() const {
      assert(!Node && "Reading MachineInstr of SUnit with SDNode!");
      return Instr;
    }

    /// addPred - This adds the specified edge as a pred of the current node if
    /// not already.  It also adds the current node as a successor of the
    /// specified node.
    bool addPred(const SDep &D, bool Required = true);

    /// removePred - This removes the specified edge as a pred of the current
    /// node if it exists.  It also removes the current node as a successor of
    /// the specified node.
    void removePred(const SDep &D);

    /// getDepth - Return the depth of this node, which is the length of the
    /// maximum path up to any node which has no predecessors.
    unsigned getDepth() const {
      if (!isDepthCurrent)
        const_cast<SUnit *>(this)->ComputeDepth();
      return Depth;
    }

    /// getHeight - Return the height of this node, which is the length of the
    /// maximum path down to any node which has no successors.
    unsigned getHeight() const {
      if (!isHeightCurrent)
        const_cast<SUnit *>(this)->ComputeHeight();
      return Height;
    }

    /// setDepthToAtLeast - If NewDepth is greater than this node's
    /// depth value, set it to be the new depth value. This also
    /// recursively marks successor nodes dirty.
    void setDepthToAtLeast(unsigned NewDepth);

    /// setDepthToAtLeast - If NewDepth is greater than this node's
    /// depth value, set it to be the new height value. This also
    /// recursively marks predecessor nodes dirty.
    void setHeightToAtLeast(unsigned NewHeight);

    /// setDepthDirty - Set a flag in this node to indicate that its
    /// stored Depth value will require recomputation the next time
    /// getDepth() is called.
    void setDepthDirty();

    /// setHeightDirty - Set a flag in this node to indicate that its
    /// stored Height value will require recomputation the next time
    /// getHeight() is called.
    void setHeightDirty();

    /// isPred - Test if node N is a predecessor of this node.
    bool isPred(SUnit *N) {
      for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
        if (Preds[i].getSUnit() == N)
          return true;
      return false;
    }

    /// isSucc - Test if node N is a successor of this node.
    bool isSucc(SUnit *N) {
      for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
        if (Succs[i].getSUnit() == N)
          return true;
      return false;
    }

    bool isTopReady() const {
      return NumPredsLeft == 0;
    }
    bool isBottomReady() const {
      return NumSuccsLeft == 0;
    }

    /// \brief Order this node's predecessor edges such that the critical path
    /// edge occurs first.
    void biasCriticalPath();

    void dump(const ScheduleDAG *G) const;
    void dumpAll(const ScheduleDAG *G) const;
    void print(raw_ostream &O, const ScheduleDAG *G) const;

  private:
    void ComputeDepth();
    void ComputeHeight();
  };

  //===--------------------------------------------------------------------===//
  /// SchedulingPriorityQueue - This interface is used to plug different
  /// priorities computation algorithms into the list scheduler. It implements
  /// the interface of a standard priority queue, where nodes are inserted in
  /// arbitrary order and returned in priority order.  The computation of the
  /// priority and the representation of the queue are totally up to the
  /// implementation to decide.
  ///
  class SchedulingPriorityQueue {
    virtual void anchor();
    unsigned CurCycle;
    bool HasReadyFilter;
  public:
    SchedulingPriorityQueue(bool rf = false):
      CurCycle(0), HasReadyFilter(rf) {}
    virtual ~SchedulingPriorityQueue() {}

    virtual bool isBottomUp() const = 0;

    virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
    virtual void addNode(const SUnit *SU) = 0;
    virtual void updateNode(const SUnit *SU) = 0;
    virtual void releaseState() = 0;

    virtual bool empty() const = 0;

    bool hasReadyFilter() const { return HasReadyFilter; }

    virtual bool tracksRegPressure() const { return false; }

    virtual bool isReady(SUnit *) const {
      assert(!HasReadyFilter && "The ready filter must override isReady()");
      return true;
    }
    virtual void push(SUnit *U) = 0;

    void push_all(const std::vector<SUnit *> &Nodes) {
      for (std::vector<SUnit *>::const_iterator I = Nodes.begin(),
           E = Nodes.end(); I != E; ++I)
        push(*I);
    }

    virtual SUnit *pop() = 0;

    virtual void remove(SUnit *SU) = 0;

    virtual void dump(ScheduleDAG *) const {}

    /// scheduledNode - As each node is scheduled, this method is invoked.  This
    /// allows the priority function to adjust the priority of related
    /// unscheduled nodes, for example.
    ///
    virtual void scheduledNode(SUnit *) {}

    virtual void unscheduledNode(SUnit *) {}

    void setCurCycle(unsigned Cycle) {
      CurCycle = Cycle;
    }

    unsigned getCurCycle() const {
      return CurCycle;
    }
  };

  class ScheduleDAG {
  public:
    const TargetMachine &TM;              // Target processor
    const TargetInstrInfo *TII;           // Target instruction information
    const TargetRegisterInfo *TRI;        // Target processor register info
    MachineFunction &MF;                  // Machine function
    MachineRegisterInfo &MRI;             // Virtual/real register map
    std::vector<SUnit> SUnits;            // The scheduling units.
    SUnit EntrySU;                        // Special node for the region entry.
    SUnit ExitSU;                         // Special node for the region exit.

#ifdef NDEBUG
    static const bool StressSched = false;
#else
    bool StressSched;
#endif

    explicit ScheduleDAG(MachineFunction &mf);

    virtual ~ScheduleDAG();

    /// clearDAG - clear the DAG state (between regions).
    void clearDAG();

    /// getInstrDesc - Return the MCInstrDesc of this SUnit.
    /// Return NULL for SDNodes without a machine opcode.
    const MCInstrDesc *getInstrDesc(const SUnit *SU) const {
      if (SU->isInstr()) return &SU->getInstr()->getDesc();
      return getNodeDesc(SU->getNode());
    }

    /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
    /// using 'dot'.
    ///
    virtual void viewGraph(const Twine &Name, const Twine &Title);
    virtual void viewGraph();

    virtual void dumpNode(const SUnit *SU) const = 0;

    /// getGraphNodeLabel - Return a label for an SUnit node in a visualization
    /// of the ScheduleDAG.
    virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0;

    /// getDAGLabel - Return a label for the region of code covered by the DAG.
    virtual std::string getDAGName() const = 0;

    /// addCustomGraphFeatures - Add custom features for a visualization of
    /// the ScheduleDAG.
    virtual void addCustomGraphFeatures(GraphWriter<ScheduleDAG*> &) const {}

#ifndef NDEBUG
    /// VerifyScheduledDAG - Verify that all SUnits were scheduled and that
    /// their state is consistent. Return the number of scheduled SUnits.
    unsigned VerifyScheduledDAG(bool isBottomUp);
#endif

  private:
    // Return the MCInstrDesc of this SDNode or NULL.
    const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
  };

  class SUnitIterator : public std::iterator<std::forward_iterator_tag,
                                             SUnit, ptrdiff_t> {
    SUnit *Node;
    unsigned Operand;

    SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
  public:
    bool operator==(const SUnitIterator& x) const {
      return Operand == x.Operand;
    }
    bool operator!=(const SUnitIterator& x) const { return !operator==(x); }

    const SUnitIterator &operator=(const SUnitIterator &I) {
      assert(I.Node==Node && "Cannot assign iterators to two different nodes!");
      Operand = I.Operand;
      return *this;
    }

    pointer operator*() const {
      return Node->Preds[Operand].getSUnit();
    }
    pointer operator->() const { return operator*(); }

    SUnitIterator& operator++() {                // Preincrement
      ++Operand;
      return *this;
    }
    SUnitIterator operator++(int) { // Postincrement
      SUnitIterator tmp = *this; ++*this; return tmp;
    }

    static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
    static SUnitIterator end  (SUnit *N) {
      return SUnitIterator(N, (unsigned)N->Preds.size());
    }

    unsigned getOperand() const { return Operand; }
    const SUnit *getNode() const { return Node; }
    /// isCtrlDep - Test if this is not an SDep::Data dependence.
    bool isCtrlDep() const {
      return getSDep().isCtrl();
    }
    bool isArtificialDep() const {
      return getSDep().isArtificial();
    }
    const SDep &getSDep() const {
      return Node->Preds[Operand];
    }
  };

  template <> struct GraphTraits<SUnit*> {
    typedef SUnit NodeType;
    typedef SUnitIterator ChildIteratorType;
    static inline NodeType *getEntryNode(SUnit *N) { return N; }
    static inline ChildIteratorType child_begin(NodeType *N) {
      return SUnitIterator::begin(N);
    }
    static inline ChildIteratorType child_end(NodeType *N) {
      return SUnitIterator::end(N);
    }
  };

  template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
    typedef std::vector<SUnit>::iterator nodes_iterator;
    static nodes_iterator nodes_begin(ScheduleDAG *G) {
      return G->SUnits.begin();
    }
    static nodes_iterator nodes_end(ScheduleDAG *G) {
      return G->SUnits.end();
    }
  };

  /// ScheduleDAGTopologicalSort is a class that computes a topological
  /// ordering for SUnits and provides methods for dynamically updating
  /// the ordering as new edges are added.
  ///
  /// This allows a very fast implementation of IsReachable, for example.
  ///
  class ScheduleDAGTopologicalSort {
    /// SUnits - A reference to the ScheduleDAG's SUnits.
    std::vector<SUnit> &SUnits;
    SUnit *ExitSU;

    /// Index2Node - Maps topological index to the node number.
    std::vector<int> Index2Node;
    /// Node2Index - Maps the node number to its topological index.
    std::vector<int> Node2Index;
    /// Visited - a set of nodes visited during a DFS traversal.
    BitVector Visited;

    /// DFS - make a DFS traversal and mark all nodes affected by the
    /// edge insertion. These nodes will later get new topological indexes
    /// by means of the Shift method.
    void DFS(const SUnit *SU, int UpperBound, bool& HasLoop);

    /// Shift - reassign topological indexes for the nodes in the DAG
    /// to preserve the topological ordering.
    void Shift(BitVector& Visited, int LowerBound, int UpperBound);

    /// Allocate - assign the topological index to the node n.
    void Allocate(int n, int index);

  public:
    ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, SUnit *ExitSU);

    /// InitDAGTopologicalSorting - create the initial topological
    /// ordering from the DAG to be scheduled.
    void InitDAGTopologicalSorting();

    /// IsReachable - Checks if SU is reachable from TargetSU.
    bool IsReachable(const SUnit *SU, const SUnit *TargetSU);

    /// WillCreateCycle - Return true if addPred(TargetSU, SU) creates a cycle.
    bool WillCreateCycle(SUnit *TargetSU, SUnit *SU);

    /// AddPred - Updates the topological ordering to accommodate an edge
    /// to be added from SUnit X to SUnit Y.
    void AddPred(SUnit *Y, SUnit *X);

    /// RemovePred - Updates the topological ordering to accommodate an
    /// an edge to be removed from the specified node N from the predecessors
    /// of the current node M.
    void RemovePred(SUnit *M, SUnit *N);

    typedef std::vector<int>::iterator iterator;
    typedef std::vector<int>::const_iterator const_iterator;
    iterator begin() { return Index2Node.begin(); }
    const_iterator begin() const { return Index2Node.begin(); }
    iterator end() { return Index2Node.end(); }
    const_iterator end() const { return Index2Node.end(); }

    typedef std::vector<int>::reverse_iterator reverse_iterator;
    typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
    reverse_iterator rbegin() { return Index2Node.rbegin(); }
    const_reverse_iterator rbegin() const { return Index2Node.rbegin(); }
    reverse_iterator rend() { return Index2Node.rend(); }
    const_reverse_iterator rend() const { return Index2Node.rend(); }
  };
}

#endif
