1 //===- llvm/CodeGen/ScheduleDAG.h - Common Base Class -----------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file Implements the ScheduleDAG class, which is used as the common base 10 /// class for instruction schedulers. This encapsulates the scheduling DAG, 11 /// which is shared between SelectionDAG and MachineInstr scheduling. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CODEGEN_SCHEDULEDAG_H 16 #define LLVM_CODEGEN_SCHEDULEDAG_H 17 18 #include "llvm/ADT/BitVector.h" 19 #include "llvm/ADT/PointerIntPair.h" 20 #include "llvm/ADT/SmallSet.h" 21 #include "llvm/ADT/SmallVector.h" 22 #include "llvm/ADT/iterator.h" 23 #include "llvm/CodeGen/MachineInstr.h" 24 #include "llvm/CodeGen/TargetLowering.h" 25 #include "llvm/Support/Compiler.h" 26 #include "llvm/Support/ErrorHandling.h" 27 #include <cassert> 28 #include <cstddef> 29 #include <iterator> 30 #include <string> 31 #include <vector> 32 33 namespace llvm { 34 35 template <class GraphType> struct GraphTraits; 36 template<class Graph> class GraphWriter; 37 class TargetMachine; 38 class MachineFunction; 39 class MachineRegisterInfo; 40 class MCInstrDesc; 41 struct MCSchedClassDesc; 42 class SDNode; 43 class SUnit; 44 class ScheduleDAG; 45 class TargetInstrInfo; 46 class TargetRegisterClass; 47 class TargetRegisterInfo; 48 49 /// Scheduling dependency. This represents one direction of an edge in the 50 /// scheduling DAG. 51 class SDep { 52 public: 53 /// These are the different kinds of scheduling dependencies. 54 enum Kind { 55 Data, ///< Regular data dependence (aka true-dependence). 56 Anti, ///< A register anti-dependence (aka WAR). 57 Output, ///< A register output-dependence (aka WAW). 58 Order ///< Any other ordering dependency. 59 }; 60 61 // Strong dependencies must be respected by the scheduler. Artificial 62 // dependencies may be removed only if they are redundant with another 63 // strong dependence. 64 // 65 // Weak dependencies may be violated by the scheduling strategy, but only if 66 // the strategy can prove it is correct to do so. 67 // 68 // Strong OrderKinds must occur before "Weak". 69 // Weak OrderKinds must occur after "Weak". 70 enum OrderKind { 71 Barrier, ///< An unknown scheduling barrier. 72 MayAliasMem, ///< Nonvolatile load/Store instructions that may alias. 73 MustAliasMem, ///< Nonvolatile load/Store instructions that must alias. 74 Artificial, ///< Arbitrary strong DAG edge (no real dependence). 75 Weak, ///< Arbitrary weak DAG edge. 76 Cluster ///< Weak DAG edge linking a chain of clustered instrs. 77 }; 78 79 private: 80 /// A pointer to the depending/depended-on SUnit, and an enum 81 /// indicating the kind of the dependency. 82 PointerIntPair<SUnit *, 2, Kind> Dep; 83 84 /// A union discriminated by the dependence kind. 85 union { 86 /// For Data, Anti, and Output dependencies, the associated register. For 87 /// Data dependencies that don't currently have a register/ assigned, this 88 /// is set to zero. 89 unsigned Reg; 90 91 /// Additional information about Order dependencies. 92 unsigned OrdKind; // enum OrderKind 93 } Contents; 94 95 /// The time associated with this edge. Often this is just the value of the 96 /// Latency field of the predecessor, however advanced models may provide 97 /// additional information about specific edges. 98 unsigned Latency = 0u; 99 100 public: 101 /// Constructs a null SDep. This is only for use by container classes which 102 /// require default constructors. SUnits may not/ have null SDep edges. SDep()103 SDep() : Dep(nullptr, Data) {} 104 105 /// Constructs an SDep with the specified values. SDep(SUnit * S,Kind kind,Register Reg)106 SDep(SUnit *S, Kind kind, Register Reg) : Dep(S, kind), Contents() { 107 switch (kind) { 108 default: 109 llvm_unreachable("Reg given for non-register dependence!"); 110 case Anti: 111 case Output: 112 assert(Reg && "SDep::Anti and SDep::Output must use a non-zero Reg!"); 113 Contents.Reg = Reg.id(); 114 Latency = 0; 115 break; 116 case Data: 117 Contents.Reg = Reg.id(); 118 Latency = 1; 119 break; 120 } 121 } 122 SDep(SUnit * S,OrderKind kind)123 SDep(SUnit *S, OrderKind kind) 124 : Dep(S, Order), Contents(), Latency(0) { 125 Contents.OrdKind = kind; 126 } 127 128 /// Returns true if the specified SDep is equivalent except for latency. 129 bool overlaps(const SDep &Other) const; 130 131 bool operator==(const SDep &Other) const { 132 return overlaps(Other) && Latency == Other.Latency; 133 } 134 135 bool operator!=(const SDep &Other) const { 136 return !operator==(Other); 137 } 138 139 /// Returns the latency value for this edge, which roughly means the 140 /// minimum number of cycles that must elapse between the predecessor and 141 /// the successor, given that they have this edge between them. getLatency()142 unsigned getLatency() const { 143 return Latency; 144 } 145 146 /// Sets the latency for this edge. setLatency(unsigned Lat)147 void setLatency(unsigned Lat) { 148 Latency = Lat; 149 } 150 151 //// Returns the SUnit to which this edge points. 152 SUnit *getSUnit() const; 153 154 //// Assigns the SUnit to which this edge points. 155 void setSUnit(SUnit *SU); 156 157 /// Returns an enum value representing the kind of the dependence. 158 Kind getKind() const; 159 160 /// Shorthand for getKind() != SDep::Data. isCtrl()161 bool isCtrl() const { 162 return getKind() != Data; 163 } 164 165 /// Tests if this is an Order dependence between two memory accesses 166 /// where both sides of the dependence access memory in non-volatile and 167 /// fully modeled ways. isNormalMemory()168 bool isNormalMemory() const { 169 return getKind() == Order && (Contents.OrdKind == MayAliasMem 170 || Contents.OrdKind == MustAliasMem); 171 } 172 173 /// Tests if this is an Order dependence that is marked as a barrier. isBarrier()174 bool isBarrier() const { 175 return getKind() == Order && Contents.OrdKind == Barrier; 176 } 177 178 /// Tests if this is could be any kind of memory dependence. isNormalMemoryOrBarrier()179 bool isNormalMemoryOrBarrier() const { 180 return (isNormalMemory() || isBarrier()); 181 } 182 183 /// Tests if this is an Order dependence that is marked as 184 /// "must alias", meaning that the SUnits at either end of the edge have a 185 /// memory dependence on a known memory location. isMustAlias()186 bool isMustAlias() const { 187 return getKind() == Order && Contents.OrdKind == MustAliasMem; 188 } 189 190 /// Tests if this a weak dependence. Weak dependencies are considered DAG 191 /// edges for height computation and other heuristics, but do not force 192 /// ordering. Breaking a weak edge may require the scheduler to compensate, 193 /// for example by inserting a copy. isWeak()194 bool isWeak() const { 195 return getKind() == Order && Contents.OrdKind >= Weak; 196 } 197 198 /// Tests if this is an Order dependence that is marked as 199 /// "artificial", meaning it isn't necessary for correctness. isArtificial()200 bool isArtificial() const { 201 return getKind() == Order && Contents.OrdKind == Artificial; 202 } 203 204 /// Tests if this is an Order dependence that is marked as "cluster", 205 /// meaning it is artificial and wants to be adjacent. isCluster()206 bool isCluster() const { 207 return getKind() == Order && Contents.OrdKind == Cluster; 208 } 209 210 /// Tests if this is a Data dependence that is associated with a register. isAssignedRegDep()211 bool isAssignedRegDep() const { return getKind() == Data && Contents.Reg; } 212 213 /// Returns the register associated with this edge. This is only valid on 214 /// Data, Anti, and Output edges. On Data edges, this value may be zero, 215 /// meaning there is no associated register. getReg()216 Register getReg() const { 217 assert((getKind() == Data || getKind() == Anti || getKind() == Output) && 218 "getReg called on non-register dependence edge!"); 219 return Contents.Reg; 220 } 221 222 /// Assigns the associated register for this edge. This is only valid on 223 /// Data, Anti, and Output edges. On Anti and Output edges, this value must 224 /// not be zero. On Data edges, the value may be zero, which would mean that 225 /// no specific register is associated with this edge. setReg(Register Reg)226 void setReg(Register Reg) { 227 assert((getKind() == Data || getKind() == Anti || getKind() == Output) && 228 "setReg called on non-register dependence edge!"); 229 assert((getKind() != Anti || Reg) && 230 "SDep::Anti edge cannot use the zero register!"); 231 assert((getKind() != Output || Reg) && 232 "SDep::Output edge cannot use the zero register!"); 233 Contents.Reg = Reg.id(); 234 } 235 236 LLVM_ABI void dump(const TargetRegisterInfo *TRI = nullptr) const; 237 }; 238 239 /// Keep record of which SUnit are in the same cluster group. 240 typedef SmallSet<SUnit *, 8> ClusterInfo; 241 constexpr unsigned InvalidClusterId = ~0u; 242 243 /// Scheduling unit. This is a node in the scheduling DAG. 244 class SUnit { 245 private: 246 enum : unsigned { BoundaryID = ~0u }; 247 248 union { 249 SDNode *Node; ///< Representative node. 250 MachineInstr *Instr; ///< Alternatively, a MachineInstr. 251 }; 252 253 public: 254 SUnit *OrigNode = nullptr; ///< If not this, the node from which this node 255 /// was cloned. (SD scheduling only) 256 257 const MCSchedClassDesc *SchedClass = 258 nullptr; ///< nullptr or resolved SchedClass. 259 260 const TargetRegisterClass *CopyDstRC = 261 nullptr; ///< Is a special copy node if != nullptr. 262 const TargetRegisterClass *CopySrcRC = nullptr; 263 264 SmallVector<SDep, 4> Preds; ///< All sunit predecessors. 265 SmallVector<SDep, 4> Succs; ///< All sunit successors. 266 267 typedef SmallVectorImpl<SDep>::iterator pred_iterator; 268 typedef SmallVectorImpl<SDep>::iterator succ_iterator; 269 typedef SmallVectorImpl<SDep>::const_iterator const_pred_iterator; 270 typedef SmallVectorImpl<SDep>::const_iterator const_succ_iterator; 271 272 unsigned NodeNum = BoundaryID; ///< Entry # of node in the node vector. 273 unsigned NodeQueueId = 0; ///< Queue id of node. 274 unsigned NumPreds = 0; ///< # of SDep::Data preds. 275 unsigned NumSuccs = 0; ///< # of SDep::Data sucss. 276 unsigned NumPredsLeft = 0; ///< # of preds not scheduled. 277 unsigned NumSuccsLeft = 0; ///< # of succs not scheduled. 278 unsigned WeakPredsLeft = 0; ///< # of weak preds not scheduled. 279 unsigned WeakSuccsLeft = 0; ///< # of weak succs not scheduled. 280 unsigned TopReadyCycle = 0; ///< Cycle relative to start when node is ready. 281 unsigned BotReadyCycle = 0; ///< Cycle relative to end when node is ready. 282 283 unsigned ParentClusterIdx = InvalidClusterId; ///< The parent cluster id. 284 285 private: 286 unsigned Depth = 0; ///< Node depth. 287 unsigned Height = 0; ///< Node height. 288 289 public: 290 bool isVRegCycle : 1; ///< May use and def the same vreg. 291 bool isCall : 1; ///< Is a function call. 292 bool isCallOp : 1; ///< Is a function call operand. 293 bool isTwoAddress : 1; ///< Is a two-address instruction. 294 bool isCommutable : 1; ///< Is a commutable instruction. 295 bool hasPhysRegUses : 1; ///< Has physreg uses. 296 bool hasPhysRegDefs : 1; ///< Has physreg defs that are being used. 297 bool hasPhysRegClobbers : 1; ///< Has any physreg defs, used or not. 298 bool isPending : 1; ///< True once pending. 299 bool isAvailable : 1; ///< True once available. 300 bool isScheduled : 1; ///< True once scheduled. 301 bool isScheduleHigh : 1; ///< True if preferable to schedule high. 302 bool isScheduleLow : 1; ///< True if preferable to schedule low. 303 bool isCloned : 1; ///< True if this node has been cloned. 304 bool isUnbuffered : 1; ///< Uses an unbuffered resource. 305 bool hasReservedResource : 1; ///< Uses a reserved resource. 306 unsigned short NumRegDefsLeft = 0; ///< # of reg defs with no scheduled use. 307 unsigned short Latency = 0; ///< Node latency. 308 309 private: 310 bool isDepthCurrent : 1; ///< True if Depth is current. 311 bool isHeightCurrent : 1; ///< True if Height is current. 312 bool isNode : 1; ///< True if the representative is an SDNode 313 bool isInst : 1; ///< True if the representative is a MachineInstr 314 315 public: 316 Sched::Preference SchedulingPref : 4; ///< Scheduling preference. 317 static_assert(Sched::Preference::Last <= (1 << 4), 318 "not enough bits in bitfield"); 319 320 /// Constructs an SUnit for pre-regalloc scheduling to represent an 321 /// SDNode and any nodes flagged to it. SUnit(SDNode * node,unsigned nodenum)322 SUnit(SDNode *node, unsigned nodenum) 323 : Node(node), NodeNum(nodenum), isVRegCycle(false), isCall(false), 324 isCallOp(false), isTwoAddress(false), isCommutable(false), 325 hasPhysRegUses(false), hasPhysRegDefs(false), 326 hasPhysRegClobbers(false), isPending(false), isAvailable(false), 327 isScheduled(false), isScheduleHigh(false), isScheduleLow(false), 328 isCloned(false), isUnbuffered(false), hasReservedResource(false), 329 isDepthCurrent(false), isHeightCurrent(false), isNode(true), 330 isInst(false), SchedulingPref(Sched::None) {} 331 332 /// Constructs an SUnit for post-regalloc scheduling to represent a 333 /// MachineInstr. SUnit(MachineInstr * instr,unsigned nodenum)334 SUnit(MachineInstr *instr, unsigned nodenum) 335 : Instr(instr), NodeNum(nodenum), isVRegCycle(false), isCall(false), 336 isCallOp(false), isTwoAddress(false), isCommutable(false), 337 hasPhysRegUses(false), hasPhysRegDefs(false), 338 hasPhysRegClobbers(false), isPending(false), isAvailable(false), 339 isScheduled(false), isScheduleHigh(false), isScheduleLow(false), 340 isCloned(false), isUnbuffered(false), hasReservedResource(false), 341 isDepthCurrent(false), isHeightCurrent(false), isNode(false), 342 isInst(true), SchedulingPref(Sched::None) {} 343 344 /// Constructs a placeholder SUnit. SUnit()345 SUnit() 346 : Node(nullptr), isVRegCycle(false), isCall(false), isCallOp(false), 347 isTwoAddress(false), isCommutable(false), hasPhysRegUses(false), 348 hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), 349 isAvailable(false), isScheduled(false), isScheduleHigh(false), 350 isScheduleLow(false), isCloned(false), isUnbuffered(false), 351 hasReservedResource(false), isDepthCurrent(false), 352 isHeightCurrent(false), isNode(false), isInst(false), 353 SchedulingPref(Sched::None) {} 354 355 /// Boundary nodes are placeholders for the boundary of the 356 /// scheduling region. 357 /// 358 /// BoundaryNodes can have DAG edges, including Data edges, but they do not 359 /// correspond to schedulable entities (e.g. instructions) and do not have a 360 /// valid ID. Consequently, always check for boundary nodes before accessing 361 /// an associative data structure keyed on node ID. isBoundaryNode()362 bool isBoundaryNode() const { return NodeNum == BoundaryID; } 363 364 /// Assigns the representative SDNode for this SUnit. This may be used 365 /// during pre-regalloc scheduling. setNode(SDNode * N)366 void setNode(SDNode *N) { 367 assert(!isInst && "Setting SDNode of SUnit with MachineInstr!"); 368 Node = N; 369 isNode = true; 370 } 371 372 /// Returns the representative SDNode for this SUnit. This may be used 373 /// during pre-regalloc scheduling. getNode()374 SDNode *getNode() const { 375 assert(!isInst && (isNode || !Instr) && 376 "Reading SDNode of SUnit without SDNode!"); 377 return Node; 378 } 379 380 /// Returns true if this SUnit refers to a machine instruction as 381 /// opposed to an SDNode. isInstr()382 bool isInstr() const { return isInst && Instr; } 383 384 /// Assigns the instruction for the SUnit. This may be used during 385 /// post-regalloc scheduling. setInstr(MachineInstr * MI)386 void setInstr(MachineInstr *MI) { 387 assert(!isNode && "Setting MachineInstr of SUnit with SDNode!"); 388 Instr = MI; 389 isInst = true; 390 } 391 392 /// Returns the representative MachineInstr for this SUnit. This may be used 393 /// during post-regalloc scheduling. getInstr()394 MachineInstr *getInstr() const { 395 assert(!isNode && (isInst || !Node) && 396 "Reading MachineInstr of SUnit without MachineInstr!"); 397 return Instr; 398 } 399 400 /// Adds the specified edge as a pred of the current node if not already. 401 /// It also adds the current node as a successor of the specified node. 402 LLVM_ABI bool addPred(const SDep &D, bool Required = true); 403 404 /// Adds a barrier edge to SU by calling addPred(), with latency 0 405 /// generally or latency 1 for a store followed by a load. addPredBarrier(SUnit * SU)406 bool addPredBarrier(SUnit *SU) { 407 SDep Dep(SU, SDep::Barrier); 408 unsigned TrueMemOrderLatency = 409 ((SU->getInstr()->mayStore() && this->getInstr()->mayLoad()) ? 1 : 0); 410 Dep.setLatency(TrueMemOrderLatency); 411 return addPred(Dep); 412 } 413 414 /// Removes the specified edge as a pred of the current node if it exists. 415 /// It also removes the current node as a successor of the specified node. 416 LLVM_ABI void removePred(const SDep &D); 417 418 /// Returns the depth of this node, which is the length of the maximum path 419 /// up to any node which has no predecessors. getDepth()420 unsigned getDepth() const { 421 if (!isDepthCurrent) 422 const_cast<SUnit *>(this)->ComputeDepth(); 423 return Depth; 424 } 425 426 /// Returns the height of this node, which is the length of the 427 /// maximum path down to any node which has no successors. getHeight()428 unsigned getHeight() const { 429 if (!isHeightCurrent) 430 const_cast<SUnit *>(this)->ComputeHeight(); 431 return Height; 432 } 433 434 /// If NewDepth is greater than this node's depth value, sets it to 435 /// be the new depth value. This also recursively marks successor nodes 436 /// dirty. 437 LLVM_ABI void setDepthToAtLeast(unsigned NewDepth); 438 439 /// If NewHeight is greater than this node's height value, set it to be 440 /// the new height value. This also recursively marks predecessor nodes 441 /// dirty. 442 LLVM_ABI void setHeightToAtLeast(unsigned NewHeight); 443 444 /// Sets a flag in this node to indicate that its stored Depth value 445 /// will require recomputation the next time getDepth() is called. 446 LLVM_ABI void setDepthDirty(); 447 448 /// Sets a flag in this node to indicate that its stored Height value 449 /// will require recomputation the next time getHeight() is called. 450 LLVM_ABI void setHeightDirty(); 451 452 /// Tests if node N is a predecessor of this node. isPred(const SUnit * N)453 bool isPred(const SUnit *N) const { 454 for (const SDep &Pred : Preds) 455 if (Pred.getSUnit() == N) 456 return true; 457 return false; 458 } 459 460 /// Tests if node N is a successor of this node. isSucc(const SUnit * N)461 bool isSucc(const SUnit *N) const { 462 for (const SDep &Succ : Succs) 463 if (Succ.getSUnit() == N) 464 return true; 465 return false; 466 } 467 isTopReady()468 bool isTopReady() const { 469 return NumPredsLeft == 0; 470 } isBottomReady()471 bool isBottomReady() const { 472 return NumSuccsLeft == 0; 473 } 474 475 /// Orders this node's predecessor edges such that the critical path 476 /// edge occurs first. 477 LLVM_ABI void biasCriticalPath(); 478 479 LLVM_ABI void dumpAttributes() const; 480 481 private: 482 LLVM_ABI void ComputeDepth(); 483 LLVM_ABI void ComputeHeight(); 484 }; 485 486 /// Returns true if the specified SDep is equivalent except for latency. overlaps(const SDep & Other)487 inline bool SDep::overlaps(const SDep &Other) const { 488 if (Dep != Other.Dep) 489 return false; 490 switch (Dep.getInt()) { 491 case Data: 492 case Anti: 493 case Output: 494 return Contents.Reg == Other.Contents.Reg; 495 case Order: 496 return Contents.OrdKind == Other.Contents.OrdKind; 497 } 498 llvm_unreachable("Invalid dependency kind!"); 499 } 500 501 //// Returns the SUnit to which this edge points. getSUnit()502 inline SUnit *SDep::getSUnit() const { return Dep.getPointer(); } 503 504 //// Assigns the SUnit to which this edge points. setSUnit(SUnit * SU)505 inline void SDep::setSUnit(SUnit *SU) { Dep.setPointer(SU); } 506 507 /// Returns an enum value representing the kind of the dependence. getKind()508 inline SDep::Kind SDep::getKind() const { return Dep.getInt(); } 509 510 //===--------------------------------------------------------------------===// 511 512 /// This interface is used to plug different priorities computation 513 /// algorithms into the list scheduler. It implements the interface of a 514 /// standard priority queue, where nodes are inserted in arbitrary order and 515 /// returned in priority order. The computation of the priority and the 516 /// representation of the queue are totally up to the implementation to 517 /// decide. 518 class LLVM_ABI SchedulingPriorityQueue { 519 virtual void anchor(); 520 521 unsigned CurCycle = 0; 522 bool HasReadyFilter; 523 524 public: HasReadyFilter(rf)525 SchedulingPriorityQueue(bool rf = false) : HasReadyFilter(rf) {} 526 527 virtual ~SchedulingPriorityQueue() = default; 528 529 virtual bool isBottomUp() const = 0; 530 531 virtual void initNodes(std::vector<SUnit> &SUnits) = 0; 532 virtual void addNode(const SUnit *SU) = 0; 533 virtual void updateNode(const SUnit *SU) = 0; 534 virtual void releaseState() = 0; 535 536 virtual bool empty() const = 0; 537 hasReadyFilter()538 bool hasReadyFilter() const { return HasReadyFilter; } 539 tracksRegPressure()540 virtual bool tracksRegPressure() const { return false; } 541 isReady(SUnit *)542 virtual bool isReady(SUnit *) const { 543 assert(!HasReadyFilter && "The ready filter must override isReady()"); 544 return true; 545 } 546 547 virtual void push(SUnit *U) = 0; 548 push_all(const std::vector<SUnit * > & Nodes)549 void push_all(const std::vector<SUnit *> &Nodes) { 550 for (SUnit *SU : Nodes) 551 push(SU); 552 } 553 554 virtual SUnit *pop() = 0; 555 556 virtual void remove(SUnit *SU) = 0; 557 dump(ScheduleDAG *)558 virtual void dump(ScheduleDAG *) const {} 559 560 /// As each node is scheduled, this method is invoked. This allows the 561 /// priority function to adjust the priority of related unscheduled nodes, 562 /// for example. scheduledNode(SUnit *)563 virtual void scheduledNode(SUnit *) {} 564 unscheduledNode(SUnit *)565 virtual void unscheduledNode(SUnit *) {} 566 setCurCycle(unsigned Cycle)567 void setCurCycle(unsigned Cycle) { 568 CurCycle = Cycle; 569 } 570 getCurCycle()571 unsigned getCurCycle() const { 572 return CurCycle; 573 } 574 }; 575 576 class LLVM_ABI ScheduleDAG { 577 public: 578 const TargetMachine &TM; ///< Target processor 579 const TargetInstrInfo *TII; ///< Target instruction information 580 const TargetRegisterInfo *TRI; ///< Target processor register info 581 MachineFunction &MF; ///< Machine function 582 MachineRegisterInfo &MRI; ///< Virtual/real register map 583 std::vector<SUnit> SUnits; ///< The scheduling units. 584 SUnit EntrySU; ///< Special node for the region entry. 585 SUnit ExitSU; ///< Special node for the region exit. 586 587 #ifdef NDEBUG 588 static const bool StressSched = false; 589 #else 590 bool StressSched; 591 #endif 592 593 // This class is designed to be passed by reference only. Copy constructor 594 // is declared as deleted here to make the derived classes have deleted 595 // implicit-declared copy constructor, which suppresses the warnings from 596 // static analyzer when the derived classes own resources that are freed in 597 // their destructors, but don't have user-written copy constructors (rule 598 // of three). 599 ScheduleDAG(const ScheduleDAG &) = delete; 600 ScheduleDAG &operator=(const ScheduleDAG &) = delete; 601 602 explicit ScheduleDAG(MachineFunction &mf); 603 604 virtual ~ScheduleDAG(); 605 606 /// Clears the DAG state (between regions). 607 void clearDAG(); 608 609 /// Returns the MCInstrDesc of this SUnit. 610 /// Returns NULL for SDNodes without a machine opcode. getInstrDesc(const SUnit * SU)611 const MCInstrDesc *getInstrDesc(const SUnit *SU) const { 612 if (SU->isInstr()) return &SU->getInstr()->getDesc(); 613 return getNodeDesc(SU->getNode()); 614 } 615 616 /// Pops up a GraphViz/gv window with the ScheduleDAG rendered using 'dot'. 617 virtual void viewGraph(const Twine &Name, const Twine &Title); 618 virtual void viewGraph(); 619 620 virtual void dumpNode(const SUnit &SU) const = 0; 621 virtual void dump() const = 0; 622 void dumpNodeName(const SUnit &SU) const; 623 624 /// Returns a label for an SUnit node in a visualization of the ScheduleDAG. 625 virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0; 626 627 /// Returns a label for the region of code covered by the DAG. 628 virtual std::string getDAGName() const = 0; 629 630 /// Adds custom features for a visualization of the ScheduleDAG. addCustomGraphFeatures(GraphWriter<ScheduleDAG * > &)631 virtual void addCustomGraphFeatures(GraphWriter<ScheduleDAG*> &) const {} 632 633 #ifndef NDEBUG 634 /// Verifies that all SUnits were scheduled and that their state is 635 /// consistent. Returns the number of scheduled SUnits. 636 unsigned VerifyScheduledDAG(bool isBottomUp); 637 #endif 638 639 protected: 640 void dumpNodeAll(const SUnit &SU) const; 641 642 private: 643 /// Returns the MCInstrDesc of this SDNode or NULL. 644 const MCInstrDesc *getNodeDesc(const SDNode *Node) const; 645 }; 646 647 class SUnitIterator { 648 SUnit *Node; 649 unsigned Operand; 650 SUnitIterator(SUnit * N,unsigned Op)651 SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {} 652 653 public: 654 using iterator_category = std::forward_iterator_tag; 655 using value_type = SUnit; 656 using difference_type = std::ptrdiff_t; 657 using pointer = value_type *; 658 using reference = value_type &; 659 660 bool operator==(const SUnitIterator& x) const { 661 return Operand == x.Operand; 662 } 663 bool operator!=(const SUnitIterator& x) const { return !operator==(x); } 664 665 pointer operator*() const { 666 return Node->Preds[Operand].getSUnit(); 667 } 668 pointer operator->() const { return operator*(); } 669 670 SUnitIterator& operator++() { // Preincrement 671 ++Operand; 672 return *this; 673 } 674 SUnitIterator operator++(int) { // Postincrement 675 SUnitIterator tmp = *this; ++*this; return tmp; 676 } 677 begin(SUnit * N)678 static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); } end(SUnit * N)679 static SUnitIterator end (SUnit *N) { 680 return SUnitIterator(N, (unsigned)N->Preds.size()); 681 } 682 getOperand()683 unsigned getOperand() const { return Operand; } getNode()684 const SUnit *getNode() const { return Node; } 685 686 /// Tests if this is not an SDep::Data dependence. isCtrlDep()687 bool isCtrlDep() const { 688 return getSDep().isCtrl(); 689 } isArtificialDep()690 bool isArtificialDep() const { 691 return getSDep().isArtificial(); 692 } getSDep()693 const SDep &getSDep() const { 694 return Node->Preds[Operand]; 695 } 696 }; 697 698 template <> struct GraphTraits<SUnit*> { 699 typedef SUnit *NodeRef; 700 typedef SUnitIterator ChildIteratorType; 701 static NodeRef getEntryNode(SUnit *N) { return N; } 702 static ChildIteratorType child_begin(NodeRef N) { 703 return SUnitIterator::begin(N); 704 } 705 static ChildIteratorType child_end(NodeRef N) { 706 return SUnitIterator::end(N); 707 } 708 }; 709 710 template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> { 711 typedef pointer_iterator<std::vector<SUnit>::iterator> nodes_iterator; 712 static nodes_iterator nodes_begin(ScheduleDAG *G) { 713 return nodes_iterator(G->SUnits.begin()); 714 } 715 static nodes_iterator nodes_end(ScheduleDAG *G) { 716 return nodes_iterator(G->SUnits.end()); 717 } 718 }; 719 720 /// This class can compute a topological ordering for SUnits and provides 721 /// methods for dynamically updating the ordering as new edges are added. 722 /// 723 /// This allows a very fast implementation of IsReachable, for example. 724 class ScheduleDAGTopologicalSort { 725 /// A reference to the ScheduleDAG's SUnits. 726 std::vector<SUnit> &SUnits; 727 SUnit *ExitSU; 728 729 // Have any new nodes been added? 730 bool Dirty = false; 731 732 // Outstanding added edges, that have not been applied to the ordering. 733 SmallVector<std::pair<SUnit *, SUnit *>, 16> Updates; 734 735 /// Maps topological index to the node number. 736 std::vector<int> Index2Node; 737 /// Maps the node number to its topological index. 738 std::vector<int> Node2Index; 739 /// a set of nodes visited during a DFS traversal. 740 BitVector Visited; 741 742 /// Makes a DFS traversal and mark all nodes affected by the edge insertion. 743 /// These nodes will later get new topological indexes by means of the Shift 744 /// method. 745 void DFS(const SUnit *SU, int UpperBound, bool& HasLoop); 746 747 /// Reassigns topological indexes for the nodes in the DAG to 748 /// preserve the topological ordering. 749 void Shift(BitVector& Visited, int LowerBound, int UpperBound); 750 751 /// Assigns the topological index to the node n. 752 void Allocate(int n, int index); 753 754 /// Fix the ordering, by either recomputing from scratch or by applying 755 /// any outstanding updates. Uses a heuristic to estimate what will be 756 /// cheaper. 757 void FixOrder(); 758 759 public: 760 LLVM_ABI ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, 761 SUnit *ExitSU); 762 763 /// Add a SUnit without predecessors to the end of the topological order. It 764 /// also must be the first new node added to the DAG. 765 LLVM_ABI void AddSUnitWithoutPredecessors(const SUnit *SU); 766 767 /// Creates the initial topological ordering from the DAG to be scheduled. 768 LLVM_ABI void InitDAGTopologicalSorting(); 769 770 /// Returns an array of SUs that are both in the successor 771 /// subtree of StartSU and in the predecessor subtree of TargetSU. 772 /// StartSU and TargetSU are not in the array. 773 /// Success is false if TargetSU is not in the successor subtree of 774 /// StartSU, else it is true. 775 LLVM_ABI std::vector<int> GetSubGraph(const SUnit &StartSU, 776 const SUnit &TargetSU, bool &Success); 777 778 /// Checks if \p SU is reachable from \p TargetSU. 779 LLVM_ABI bool IsReachable(const SUnit *SU, const SUnit *TargetSU); 780 781 /// Returns true if addPred(TargetSU, SU) creates a cycle. 782 LLVM_ABI bool WillCreateCycle(SUnit *TargetSU, SUnit *SU); 783 784 /// Updates the topological ordering to accommodate an edge to be 785 /// added from SUnit \p X to SUnit \p Y. 786 LLVM_ABI void AddPred(SUnit *Y, SUnit *X); 787 788 /// Queues an update to the topological ordering to accommodate an edge to 789 /// be added from SUnit \p X to SUnit \p Y. 790 LLVM_ABI void AddPredQueued(SUnit *Y, SUnit *X); 791 792 /// Updates the topological ordering to accommodate an edge to be 793 /// removed from the specified node \p N from the predecessors of the 794 /// current node \p M. 795 LLVM_ABI void RemovePred(SUnit *M, SUnit *N); 796 797 /// Mark the ordering as temporarily broken, after a new node has been 798 /// added. 799 void MarkDirty() { Dirty = true; } 800 801 typedef std::vector<int>::iterator iterator; 802 typedef std::vector<int>::const_iterator const_iterator; 803 iterator begin() { return Index2Node.begin(); } 804 const_iterator begin() const { return Index2Node.begin(); } 805 iterator end() { return Index2Node.end(); } 806 const_iterator end() const { return Index2Node.end(); } 807 808 typedef std::vector<int>::reverse_iterator reverse_iterator; 809 typedef std::vector<int>::const_reverse_iterator const_reverse_iterator; 810 reverse_iterator rbegin() { return Index2Node.rbegin(); } 811 const_reverse_iterator rbegin() const { return Index2Node.rbegin(); } 812 reverse_iterator rend() { return Index2Node.rend(); } 813 const_reverse_iterator rend() const { return Index2Node.rend(); } 814 }; 815 816 } // end namespace llvm 817 818 #endif // LLVM_CODEGEN_SCHEDULEDAG_H 819