ScheduleDAG.h 29 KB

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