ScheduleDAG.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. //===---- ScheduleDAG.cpp - Implement the ScheduleDAG class ---------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This implements the ScheduleDAG class, which is a base class used by
  11. // scheduling implementation classes.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/CodeGen/ScheduleDAG.h"
  15. #include "llvm/CodeGen/ScheduleHazardRecognizer.h"
  16. #include "llvm/CodeGen/SelectionDAGNodes.h"
  17. #include "llvm/Support/CommandLine.h"
  18. #include "llvm/Support/Debug.h"
  19. #include "llvm/Support/raw_ostream.h"
  20. #include "llvm/Target/TargetInstrInfo.h"
  21. #include "llvm/Target/TargetMachine.h"
  22. #include "llvm/Target/TargetRegisterInfo.h"
  23. #include "llvm/Target/TargetSubtargetInfo.h"
  24. #include <climits>
  25. using namespace llvm;
  26. #define DEBUG_TYPE "pre-RA-sched"
  27. #ifndef NDEBUG
  28. static cl::opt<bool> StressSchedOpt(
  29. "stress-sched", cl::Hidden, cl::init(false),
  30. cl::desc("Stress test instruction scheduling"));
  31. #endif
  32. void SchedulingPriorityQueue::anchor() { }
  33. ScheduleDAG::ScheduleDAG(MachineFunction &mf)
  34. : TM(mf.getTarget()), TII(mf.getSubtarget().getInstrInfo()),
  35. TRI(mf.getSubtarget().getRegisterInfo()), MF(mf),
  36. MRI(mf.getRegInfo()), EntrySU(), ExitSU() {
  37. #ifndef NDEBUG
  38. StressSched = StressSchedOpt;
  39. #endif
  40. }
  41. ScheduleDAG::~ScheduleDAG() {}
  42. /// Clear the DAG state (e.g. between scheduling regions).
  43. void ScheduleDAG::clearDAG() {
  44. SUnits.clear();
  45. EntrySU = SUnit();
  46. ExitSU = SUnit();
  47. }
  48. /// getInstrDesc helper to handle SDNodes.
  49. const MCInstrDesc *ScheduleDAG::getNodeDesc(const SDNode *Node) const {
  50. if (!Node || !Node->isMachineOpcode()) return nullptr;
  51. return &TII->get(Node->getMachineOpcode());
  52. }
  53. /// addPred - This adds the specified edge as a pred of the current node if
  54. /// not already. It also adds the current node as a successor of the
  55. /// specified node.
  56. bool SUnit::addPred(const SDep &D, bool Required) {
  57. // If this node already has this dependence, don't add a redundant one.
  58. for (SmallVectorImpl<SDep>::iterator I = Preds.begin(), E = Preds.end();
  59. I != E; ++I) {
  60. // Zero-latency weak edges may be added purely for heuristic ordering. Don't
  61. // add them if another kind of edge already exists.
  62. if (!Required && I->getSUnit() == D.getSUnit())
  63. return false;
  64. if (I->overlaps(D)) {
  65. // Extend the latency if needed. Equivalent to removePred(I) + addPred(D).
  66. if (I->getLatency() < D.getLatency()) {
  67. SUnit *PredSU = I->getSUnit();
  68. // Find the corresponding successor in N.
  69. SDep ForwardD = *I;
  70. ForwardD.setSUnit(this);
  71. for (SmallVectorImpl<SDep>::iterator II = PredSU->Succs.begin(),
  72. EE = PredSU->Succs.end(); II != EE; ++II) {
  73. if (*II == ForwardD) {
  74. II->setLatency(D.getLatency());
  75. break;
  76. }
  77. }
  78. I->setLatency(D.getLatency());
  79. }
  80. return false;
  81. }
  82. }
  83. // Now add a corresponding succ to N.
  84. SDep P = D;
  85. P.setSUnit(this);
  86. SUnit *N = D.getSUnit();
  87. // Update the bookkeeping.
  88. if (D.getKind() == SDep::Data) {
  89. assert(NumPreds < UINT_MAX && "NumPreds will overflow!");
  90. assert(N->NumSuccs < UINT_MAX && "NumSuccs will overflow!");
  91. ++NumPreds;
  92. ++N->NumSuccs;
  93. }
  94. if (!N->isScheduled) {
  95. if (D.isWeak()) {
  96. ++WeakPredsLeft;
  97. }
  98. else {
  99. assert(NumPredsLeft < UINT_MAX && "NumPredsLeft will overflow!");
  100. ++NumPredsLeft;
  101. }
  102. }
  103. if (!isScheduled) {
  104. if (D.isWeak()) {
  105. ++N->WeakSuccsLeft;
  106. }
  107. else {
  108. assert(N->NumSuccsLeft < UINT_MAX && "NumSuccsLeft will overflow!");
  109. ++N->NumSuccsLeft;
  110. }
  111. }
  112. Preds.push_back(D);
  113. N->Succs.push_back(P);
  114. if (P.getLatency() != 0) {
  115. this->setDepthDirty();
  116. N->setHeightDirty();
  117. }
  118. return true;
  119. }
  120. /// removePred - This removes the specified edge as a pred of the current
  121. /// node if it exists. It also removes the current node as a successor of
  122. /// the specified node.
  123. void SUnit::removePred(const SDep &D) {
  124. // Find the matching predecessor.
  125. for (SmallVectorImpl<SDep>::iterator I = Preds.begin(), E = Preds.end();
  126. I != E; ++I)
  127. if (*I == D) {
  128. // Find the corresponding successor in N.
  129. SDep P = D;
  130. P.setSUnit(this);
  131. SUnit *N = D.getSUnit();
  132. SmallVectorImpl<SDep>::iterator Succ = std::find(N->Succs.begin(),
  133. N->Succs.end(), P);
  134. assert(Succ != N->Succs.end() && "Mismatching preds / succs lists!");
  135. N->Succs.erase(Succ);
  136. Preds.erase(I);
  137. // Update the bookkeeping.
  138. if (P.getKind() == SDep::Data) {
  139. assert(NumPreds > 0 && "NumPreds will underflow!");
  140. assert(N->NumSuccs > 0 && "NumSuccs will underflow!");
  141. --NumPreds;
  142. --N->NumSuccs;
  143. }
  144. if (!N->isScheduled) {
  145. if (D.isWeak())
  146. --WeakPredsLeft;
  147. else {
  148. assert(NumPredsLeft > 0 && "NumPredsLeft will underflow!");
  149. --NumPredsLeft;
  150. }
  151. }
  152. if (!isScheduled) {
  153. if (D.isWeak())
  154. --N->WeakSuccsLeft;
  155. else {
  156. assert(N->NumSuccsLeft > 0 && "NumSuccsLeft will underflow!");
  157. --N->NumSuccsLeft;
  158. }
  159. }
  160. if (P.getLatency() != 0) {
  161. this->setDepthDirty();
  162. N->setHeightDirty();
  163. }
  164. return;
  165. }
  166. }
  167. void SUnit::setDepthDirty() {
  168. if (!isDepthCurrent) return;
  169. SmallVector<SUnit*, 8> WorkList;
  170. WorkList.push_back(this);
  171. do {
  172. SUnit *SU = WorkList.pop_back_val();
  173. SU->isDepthCurrent = false;
  174. for (SUnit::const_succ_iterator I = SU->Succs.begin(),
  175. E = SU->Succs.end(); I != E; ++I) {
  176. SUnit *SuccSU = I->getSUnit();
  177. if (SuccSU->isDepthCurrent)
  178. WorkList.push_back(SuccSU);
  179. }
  180. } while (!WorkList.empty());
  181. }
  182. void SUnit::setHeightDirty() {
  183. if (!isHeightCurrent) return;
  184. SmallVector<SUnit*, 8> WorkList;
  185. WorkList.push_back(this);
  186. do {
  187. SUnit *SU = WorkList.pop_back_val();
  188. SU->isHeightCurrent = false;
  189. for (SUnit::const_pred_iterator I = SU->Preds.begin(),
  190. E = SU->Preds.end(); I != E; ++I) {
  191. SUnit *PredSU = I->getSUnit();
  192. if (PredSU->isHeightCurrent)
  193. WorkList.push_back(PredSU);
  194. }
  195. } while (!WorkList.empty());
  196. }
  197. /// setDepthToAtLeast - Update this node's successors to reflect the
  198. /// fact that this node's depth just increased.
  199. ///
  200. void SUnit::setDepthToAtLeast(unsigned NewDepth) {
  201. if (NewDepth <= getDepth())
  202. return;
  203. setDepthDirty();
  204. Depth = NewDepth;
  205. isDepthCurrent = true;
  206. }
  207. /// setHeightToAtLeast - Update this node's predecessors to reflect the
  208. /// fact that this node's height just increased.
  209. ///
  210. void SUnit::setHeightToAtLeast(unsigned NewHeight) {
  211. if (NewHeight <= getHeight())
  212. return;
  213. setHeightDirty();
  214. Height = NewHeight;
  215. isHeightCurrent = true;
  216. }
  217. /// ComputeDepth - Calculate the maximal path from the node to the exit.
  218. ///
  219. void SUnit::ComputeDepth() {
  220. SmallVector<SUnit*, 8> WorkList;
  221. WorkList.push_back(this);
  222. do {
  223. SUnit *Cur = WorkList.back();
  224. bool Done = true;
  225. unsigned MaxPredDepth = 0;
  226. for (SUnit::const_pred_iterator I = Cur->Preds.begin(),
  227. E = Cur->Preds.end(); I != E; ++I) {
  228. SUnit *PredSU = I->getSUnit();
  229. if (PredSU->isDepthCurrent)
  230. MaxPredDepth = std::max(MaxPredDepth,
  231. PredSU->Depth + I->getLatency());
  232. else {
  233. Done = false;
  234. WorkList.push_back(PredSU);
  235. }
  236. }
  237. if (Done) {
  238. WorkList.pop_back();
  239. if (MaxPredDepth != Cur->Depth) {
  240. Cur->setDepthDirty();
  241. Cur->Depth = MaxPredDepth;
  242. }
  243. Cur->isDepthCurrent = true;
  244. }
  245. } while (!WorkList.empty());
  246. }
  247. /// ComputeHeight - Calculate the maximal path from the node to the entry.
  248. ///
  249. void SUnit::ComputeHeight() {
  250. SmallVector<SUnit*, 8> WorkList;
  251. WorkList.push_back(this);
  252. do {
  253. SUnit *Cur = WorkList.back();
  254. bool Done = true;
  255. unsigned MaxSuccHeight = 0;
  256. for (SUnit::const_succ_iterator I = Cur->Succs.begin(),
  257. E = Cur->Succs.end(); I != E; ++I) {
  258. SUnit *SuccSU = I->getSUnit();
  259. if (SuccSU->isHeightCurrent)
  260. MaxSuccHeight = std::max(MaxSuccHeight,
  261. SuccSU->Height + I->getLatency());
  262. else {
  263. Done = false;
  264. WorkList.push_back(SuccSU);
  265. }
  266. }
  267. if (Done) {
  268. WorkList.pop_back();
  269. if (MaxSuccHeight != Cur->Height) {
  270. Cur->setHeightDirty();
  271. Cur->Height = MaxSuccHeight;
  272. }
  273. Cur->isHeightCurrent = true;
  274. }
  275. } while (!WorkList.empty());
  276. }
  277. void SUnit::biasCriticalPath() {
  278. if (NumPreds < 2)
  279. return;
  280. SUnit::pred_iterator BestI = Preds.begin();
  281. unsigned MaxDepth = BestI->getSUnit()->getDepth();
  282. for (SUnit::pred_iterator I = std::next(BestI), E = Preds.end(); I != E;
  283. ++I) {
  284. if (I->getKind() == SDep::Data && I->getSUnit()->getDepth() > MaxDepth)
  285. BestI = I;
  286. }
  287. if (BestI != Preds.begin())
  288. std::swap(*Preds.begin(), *BestI);
  289. }
  290. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  291. /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
  292. /// a group of nodes flagged together.
  293. void SUnit::dump(const ScheduleDAG *G) const {
  294. dbgs() << "SU(" << NodeNum << "): ";
  295. G->dumpNode(this);
  296. }
  297. void SUnit::dumpAll(const ScheduleDAG *G) const {
  298. dump(G);
  299. dbgs() << " # preds left : " << NumPredsLeft << "\n";
  300. dbgs() << " # succs left : " << NumSuccsLeft << "\n";
  301. if (WeakPredsLeft)
  302. dbgs() << " # weak preds left : " << WeakPredsLeft << "\n";
  303. if (WeakSuccsLeft)
  304. dbgs() << " # weak succs left : " << WeakSuccsLeft << "\n";
  305. dbgs() << " # rdefs left : " << NumRegDefsLeft << "\n";
  306. dbgs() << " Latency : " << Latency << "\n";
  307. dbgs() << " Depth : " << getDepth() << "\n";
  308. dbgs() << " Height : " << getHeight() << "\n";
  309. if (Preds.size() != 0) {
  310. dbgs() << " Predecessors:\n";
  311. for (SUnit::const_succ_iterator I = Preds.begin(), E = Preds.end();
  312. I != E; ++I) {
  313. dbgs() << " ";
  314. switch (I->getKind()) {
  315. case SDep::Data: dbgs() << "val "; break;
  316. case SDep::Anti: dbgs() << "anti"; break;
  317. case SDep::Output: dbgs() << "out "; break;
  318. case SDep::Order: dbgs() << "ch "; break;
  319. }
  320. dbgs() << "SU(" << I->getSUnit()->NodeNum << ")";
  321. if (I->isArtificial())
  322. dbgs() << " *";
  323. dbgs() << ": Latency=" << I->getLatency();
  324. if (I->isAssignedRegDep())
  325. dbgs() << " Reg=" << PrintReg(I->getReg(), G->TRI);
  326. dbgs() << "\n";
  327. }
  328. }
  329. if (Succs.size() != 0) {
  330. dbgs() << " Successors:\n";
  331. for (SUnit::const_succ_iterator I = Succs.begin(), E = Succs.end();
  332. I != E; ++I) {
  333. dbgs() << " ";
  334. switch (I->getKind()) {
  335. case SDep::Data: dbgs() << "val "; break;
  336. case SDep::Anti: dbgs() << "anti"; break;
  337. case SDep::Output: dbgs() << "out "; break;
  338. case SDep::Order: dbgs() << "ch "; break;
  339. }
  340. dbgs() << "SU(" << I->getSUnit()->NodeNum << ")";
  341. if (I->isArtificial())
  342. dbgs() << " *";
  343. dbgs() << ": Latency=" << I->getLatency();
  344. if (I->isAssignedRegDep())
  345. dbgs() << " Reg=" << PrintReg(I->getReg(), G->TRI);
  346. dbgs() << "\n";
  347. }
  348. }
  349. dbgs() << "\n";
  350. }
  351. #endif
  352. #ifndef NDEBUG
  353. /// VerifyScheduledDAG - Verify that all SUnits were scheduled and that
  354. /// their state is consistent. Return the number of scheduled nodes.
  355. ///
  356. unsigned ScheduleDAG::VerifyScheduledDAG(bool isBottomUp) {
  357. bool AnyNotSched = false;
  358. unsigned DeadNodes = 0;
  359. for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
  360. if (!SUnits[i].isScheduled) {
  361. if (SUnits[i].NumPreds == 0 && SUnits[i].NumSuccs == 0) {
  362. ++DeadNodes;
  363. continue;
  364. }
  365. if (!AnyNotSched)
  366. dbgs() << "*** Scheduling failed! ***\n";
  367. SUnits[i].dump(this);
  368. dbgs() << "has not been scheduled!\n";
  369. AnyNotSched = true;
  370. }
  371. if (SUnits[i].isScheduled &&
  372. (isBottomUp ? SUnits[i].getHeight() : SUnits[i].getDepth()) >
  373. unsigned(INT_MAX)) {
  374. if (!AnyNotSched)
  375. dbgs() << "*** Scheduling failed! ***\n";
  376. SUnits[i].dump(this);
  377. dbgs() << "has an unexpected "
  378. << (isBottomUp ? "Height" : "Depth") << " value!\n";
  379. AnyNotSched = true;
  380. }
  381. if (isBottomUp) {
  382. if (SUnits[i].NumSuccsLeft != 0) {
  383. if (!AnyNotSched)
  384. dbgs() << "*** Scheduling failed! ***\n";
  385. SUnits[i].dump(this);
  386. dbgs() << "has successors left!\n";
  387. AnyNotSched = true;
  388. }
  389. } else {
  390. if (SUnits[i].NumPredsLeft != 0) {
  391. if (!AnyNotSched)
  392. dbgs() << "*** Scheduling failed! ***\n";
  393. SUnits[i].dump(this);
  394. dbgs() << "has predecessors left!\n";
  395. AnyNotSched = true;
  396. }
  397. }
  398. }
  399. assert(!AnyNotSched);
  400. return SUnits.size() - DeadNodes;
  401. }
  402. #endif
  403. /// InitDAGTopologicalSorting - create the initial topological
  404. /// ordering from the DAG to be scheduled.
  405. ///
  406. /// The idea of the algorithm is taken from
  407. /// "Online algorithms for managing the topological order of
  408. /// a directed acyclic graph" by David J. Pearce and Paul H.J. Kelly
  409. /// This is the MNR algorithm, which was first introduced by
  410. /// A. Marchetti-Spaccamela, U. Nanni and H. Rohnert in
  411. /// "Maintaining a topological order under edge insertions".
  412. ///
  413. /// Short description of the algorithm:
  414. ///
  415. /// Topological ordering, ord, of a DAG maps each node to a topological
  416. /// index so that for all edges X->Y it is the case that ord(X) < ord(Y).
  417. ///
  418. /// This means that if there is a path from the node X to the node Z,
  419. /// then ord(X) < ord(Z).
  420. ///
  421. /// This property can be used to check for reachability of nodes:
  422. /// if Z is reachable from X, then an insertion of the edge Z->X would
  423. /// create a cycle.
  424. ///
  425. /// The algorithm first computes a topological ordering for the DAG by
  426. /// initializing the Index2Node and Node2Index arrays and then tries to keep
  427. /// the ordering up-to-date after edge insertions by reordering the DAG.
  428. ///
  429. /// On insertion of the edge X->Y, the algorithm first marks by calling DFS
  430. /// the nodes reachable from Y, and then shifts them using Shift to lie
  431. /// immediately after X in Index2Node.
  432. void ScheduleDAGTopologicalSort::InitDAGTopologicalSorting() {
  433. unsigned DAGSize = SUnits.size();
  434. std::vector<SUnit*> WorkList;
  435. WorkList.reserve(DAGSize);
  436. Index2Node.resize(DAGSize);
  437. Node2Index.resize(DAGSize);
  438. // Initialize the data structures.
  439. if (ExitSU)
  440. WorkList.push_back(ExitSU);
  441. for (unsigned i = 0, e = DAGSize; i != e; ++i) {
  442. SUnit *SU = &SUnits[i];
  443. int NodeNum = SU->NodeNum;
  444. unsigned Degree = SU->Succs.size();
  445. // Temporarily use the Node2Index array as scratch space for degree counts.
  446. Node2Index[NodeNum] = Degree;
  447. // Is it a node without dependencies?
  448. if (Degree == 0) {
  449. assert(SU->Succs.empty() && "SUnit should have no successors");
  450. // Collect leaf nodes.
  451. WorkList.push_back(SU);
  452. }
  453. }
  454. int Id = DAGSize;
  455. while (!WorkList.empty()) {
  456. SUnit *SU = WorkList.back();
  457. WorkList.pop_back();
  458. if (SU->NodeNum < DAGSize)
  459. Allocate(SU->NodeNum, --Id);
  460. for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
  461. I != E; ++I) {
  462. SUnit *SU = I->getSUnit();
  463. if (SU->NodeNum < DAGSize && !--Node2Index[SU->NodeNum])
  464. // If all dependencies of the node are processed already,
  465. // then the node can be computed now.
  466. WorkList.push_back(SU);
  467. }
  468. }
  469. Visited.resize(DAGSize);
  470. #ifndef NDEBUG
  471. // Check correctness of the ordering
  472. for (unsigned i = 0, e = DAGSize; i != e; ++i) {
  473. SUnit *SU = &SUnits[i];
  474. for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
  475. I != E; ++I) {
  476. assert(Node2Index[SU->NodeNum] > Node2Index[I->getSUnit()->NodeNum] &&
  477. "Wrong topological sorting");
  478. }
  479. }
  480. #endif
  481. }
  482. /// AddPred - Updates the topological ordering to accommodate an edge
  483. /// to be added from SUnit X to SUnit Y.
  484. void ScheduleDAGTopologicalSort::AddPred(SUnit *Y, SUnit *X) {
  485. int UpperBound, LowerBound;
  486. LowerBound = Node2Index[Y->NodeNum];
  487. UpperBound = Node2Index[X->NodeNum];
  488. bool HasLoop = false;
  489. // Is Ord(X) < Ord(Y) ?
  490. if (LowerBound < UpperBound) {
  491. // Update the topological order.
  492. Visited.reset();
  493. DFS(Y, UpperBound, HasLoop);
  494. assert(!HasLoop && "Inserted edge creates a loop!");
  495. // Recompute topological indexes.
  496. Shift(Visited, LowerBound, UpperBound);
  497. }
  498. }
  499. /// RemovePred - Updates the topological ordering to accommodate an
  500. /// an edge to be removed from the specified node N from the predecessors
  501. /// of the current node M.
  502. void ScheduleDAGTopologicalSort::RemovePred(SUnit *M, SUnit *N) {
  503. // InitDAGTopologicalSorting();
  504. }
  505. /// DFS - Make a DFS traversal to mark all nodes reachable from SU and mark
  506. /// all nodes affected by the edge insertion. These nodes will later get new
  507. /// topological indexes by means of the Shift method.
  508. void ScheduleDAGTopologicalSort::DFS(const SUnit *SU, int UpperBound,
  509. bool &HasLoop) {
  510. std::vector<const SUnit*> WorkList;
  511. WorkList.reserve(SUnits.size());
  512. WorkList.push_back(SU);
  513. do {
  514. SU = WorkList.back();
  515. WorkList.pop_back();
  516. Visited.set(SU->NodeNum);
  517. for (int I = SU->Succs.size()-1; I >= 0; --I) {
  518. unsigned s = SU->Succs[I].getSUnit()->NodeNum;
  519. // Edges to non-SUnits are allowed but ignored (e.g. ExitSU).
  520. if (s >= Node2Index.size())
  521. continue;
  522. if (Node2Index[s] == UpperBound) {
  523. HasLoop = true;
  524. return;
  525. }
  526. // Visit successors if not already and in affected region.
  527. if (!Visited.test(s) && Node2Index[s] < UpperBound) {
  528. WorkList.push_back(SU->Succs[I].getSUnit());
  529. }
  530. }
  531. } while (!WorkList.empty());
  532. }
  533. /// Shift - Renumber the nodes so that the topological ordering is
  534. /// preserved.
  535. void ScheduleDAGTopologicalSort::Shift(BitVector& Visited, int LowerBound,
  536. int UpperBound) {
  537. std::vector<int> L;
  538. int shift = 0;
  539. int i;
  540. for (i = LowerBound; i <= UpperBound; ++i) {
  541. // w is node at topological index i.
  542. int w = Index2Node[i];
  543. if (Visited.test(w)) {
  544. // Unmark.
  545. Visited.reset(w);
  546. L.push_back(w);
  547. shift = shift + 1;
  548. } else {
  549. Allocate(w, i - shift);
  550. }
  551. }
  552. for (unsigned j = 0; j < L.size(); ++j) {
  553. Allocate(L[j], i - shift);
  554. i = i + 1;
  555. }
  556. }
  557. /// WillCreateCycle - Returns true if adding an edge to TargetSU from SU will
  558. /// create a cycle. If so, it is not safe to call AddPred(TargetSU, SU).
  559. bool ScheduleDAGTopologicalSort::WillCreateCycle(SUnit *TargetSU, SUnit *SU) {
  560. // Is SU reachable from TargetSU via successor edges?
  561. if (IsReachable(SU, TargetSU))
  562. return true;
  563. for (SUnit::pred_iterator
  564. I = TargetSU->Preds.begin(), E = TargetSU->Preds.end(); I != E; ++I)
  565. if (I->isAssignedRegDep() &&
  566. IsReachable(SU, I->getSUnit()))
  567. return true;
  568. return false;
  569. }
  570. /// IsReachable - Checks if SU is reachable from TargetSU.
  571. bool ScheduleDAGTopologicalSort::IsReachable(const SUnit *SU,
  572. const SUnit *TargetSU) {
  573. // If insertion of the edge SU->TargetSU would create a cycle
  574. // then there is a path from TargetSU to SU.
  575. int UpperBound, LowerBound;
  576. LowerBound = Node2Index[TargetSU->NodeNum];
  577. UpperBound = Node2Index[SU->NodeNum];
  578. bool HasLoop = false;
  579. // Is Ord(TargetSU) < Ord(SU) ?
  580. if (LowerBound < UpperBound) {
  581. Visited.reset();
  582. // There may be a path from TargetSU to SU. Check for it.
  583. DFS(TargetSU, UpperBound, HasLoop);
  584. }
  585. return HasLoop;
  586. }
  587. /// Allocate - assign the topological index to the node n.
  588. void ScheduleDAGTopologicalSort::Allocate(int n, int index) {
  589. Node2Index[n] = index;
  590. Index2Node[index] = n;
  591. }
  592. ScheduleDAGTopologicalSort::
  593. ScheduleDAGTopologicalSort(std::vector<SUnit> &sunits, SUnit *exitsu)
  594. : SUnits(sunits), ExitSU(exitsu) {}
  595. ScheduleHazardRecognizer::~ScheduleHazardRecognizer() {}