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