ScheduleDAG.h 29 KB

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