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