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 /// 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