196f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick//===- MachineScheduler.cpp - Machine Instruction Scheduler ---------------===//
296f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick//
396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick//                     The LLVM Compiler Infrastructure
496f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick//
596f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick// This file is distributed under the University of Illinois Open Source
696f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick// License. See LICENSE.TXT for details.
796f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick//
896f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick//===----------------------------------------------------------------------===//
996f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick//
1096f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick// MachineScheduler schedules machine instructions after phi elimination. It
1196f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick// preserves LiveIntervals so it can be invoked before register allocation.
1296f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick//
1396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick//===----------------------------------------------------------------------===//
1496f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
1596f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick#define DEBUG_TYPE "misched"
1696f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
1796f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick#include "llvm/CodeGen/LiveIntervalAnalysis.h"
18c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick#include "llvm/CodeGen/MachineScheduler.h"
1996f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick#include "llvm/CodeGen/Passes.h"
20ed395c8c475692f5a43eb4b5c5562503d67616d0Andrew Trick#include "llvm/CodeGen/ScheduleDAGInstrs.h"
2196f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick#include "llvm/Analysis/AliasAnalysis.h"
22e9ef4ed13ba84ef27da831afa27b7955c8f09530Andrew Trick#include "llvm/Target/TargetInstrInfo.h"
2396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick#include "llvm/Support/CommandLine.h"
2496f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick#include "llvm/Support/Debug.h"
2596f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick#include "llvm/Support/ErrorHandling.h"
2696f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick#include "llvm/Support/raw_ostream.h"
2796f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick#include "llvm/ADT/OwningPtr.h"
2817d35e57a585e869dc3084666abd17f173723735Andrew Trick#include "llvm/ADT/PriorityQueue.h"
2996f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
30c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick#include <queue>
31c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
3296f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trickusing namespace llvm;
3396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
3417d35e57a585e869dc3084666abd17f173723735Andrew Trickstatic cl::opt<bool> ForceTopDown("misched-topdown", cl::Hidden,
3517d35e57a585e869dc3084666abd17f173723735Andrew Trick                                  cl::desc("Force top-down list scheduling"));
3617d35e57a585e869dc3084666abd17f173723735Andrew Trickstatic cl::opt<bool> ForceBottomUp("misched-bottomup", cl::Hidden,
3717d35e57a585e869dc3084666abd17f173723735Andrew Trick                                  cl::desc("Force bottom-up list scheduling"));
3817d35e57a585e869dc3084666abd17f173723735Andrew Trick
390df7f8821cc3ce26843b4fb63456cb4ccb7e4153Andrew Trick#ifndef NDEBUG
400df7f8821cc3ce26843b4fb63456cb4ccb7e4153Andrew Trickstatic cl::opt<bool> ViewMISchedDAGs("view-misched-dags", cl::Hidden,
410df7f8821cc3ce26843b4fb63456cb4ccb7e4153Andrew Trick  cl::desc("Pop up a window to show MISched dags after they are processed"));
4223f1cbbd686513ae5defbd3afdf5e286befe8a76Lang Hames
4323f1cbbd686513ae5defbd3afdf5e286befe8a76Lang Hamesstatic cl::opt<unsigned> MISchedCutoff("misched-cutoff", cl::Hidden,
4423f1cbbd686513ae5defbd3afdf5e286befe8a76Lang Hames  cl::desc("Stop scheduling after N instructions"), cl::init(~0U));
450df7f8821cc3ce26843b4fb63456cb4ccb7e4153Andrew Trick#else
460df7f8821cc3ce26843b4fb63456cb4ccb7e4153Andrew Trickstatic bool ViewMISchedDAGs = false;
470df7f8821cc3ce26843b4fb63456cb4ccb7e4153Andrew Trick#endif // NDEBUG
480df7f8821cc3ce26843b4fb63456cb4ccb7e4153Andrew Trick
495edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick//===----------------------------------------------------------------------===//
505edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick// Machine Instruction Scheduling Pass and Registry
515edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick//===----------------------------------------------------------------------===//
525edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick
5396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Tricknamespace {
5442b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick/// MachineScheduler runs after coalescing and before register allocation.
55c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trickclass MachineScheduler : public MachineSchedContext,
56c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick                         public MachineFunctionPass {
5796f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trickpublic:
5842b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick  MachineScheduler();
5996f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
6096f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
6196f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
6296f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  virtual void releaseMemory() {}
6396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
6496f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  virtual bool runOnMachineFunction(MachineFunction&);
6596f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
6696f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  virtual void print(raw_ostream &O, const Module* = 0) const;
6796f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
6896f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  static char ID; // Class identification, replacement for typeinfo
6996f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick};
7096f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick} // namespace
7196f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
7242b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trickchar MachineScheduler::ID = 0;
7396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
7442b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trickchar &llvm::MachineSchedulerID = MachineScheduler::ID;
7596f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
7642b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew TrickINITIALIZE_PASS_BEGIN(MachineScheduler, "misched",
7796f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick                      "Machine Instruction Scheduler", false, false)
7896f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew TrickINITIALIZE_AG_DEPENDENCY(AliasAnalysis)
7996f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew TrickINITIALIZE_PASS_DEPENDENCY(SlotIndexes)
8096f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew TrickINITIALIZE_PASS_DEPENDENCY(LiveIntervals)
8142b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew TrickINITIALIZE_PASS_END(MachineScheduler, "misched",
8296f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick                    "Machine Instruction Scheduler", false, false)
8396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
8442b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew TrickMachineScheduler::MachineScheduler()
85c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick: MachineFunctionPass(ID) {
8642b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick  initializeMachineSchedulerPass(*PassRegistry::getPassRegistry());
8796f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick}
8896f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
8942b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trickvoid MachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const {
9096f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  AU.setPreservesCFG();
9196f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  AU.addRequiredID(MachineDominatorsID);
9296f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  AU.addRequired<MachineLoopInfo>();
9396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  AU.addRequired<AliasAnalysis>();
94d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick  AU.addRequired<TargetPassConfig>();
9596f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  AU.addRequired<SlotIndexes>();
9696f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  AU.addPreserved<SlotIndexes>();
9796f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  AU.addRequired<LiveIntervals>();
9896f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  AU.addPreserved<LiveIntervals>();
9996f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  MachineFunctionPass::getAnalysisUsage(AU);
10096f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick}
10196f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
10296f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew TrickMachinePassRegistry MachineSchedRegistry::Registry;
10396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
104d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick/// A dummy default scheduler factory indicates whether the scheduler
105d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick/// is overridden on the command line.
106d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trickstatic ScheduleDAGInstrs *useDefaultMachineSched(MachineSchedContext *C) {
107d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick  return 0;
108d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick}
10996f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
11096f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick/// MachineSchedOpt allows command line selection of the scheduler.
11196f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trickstatic cl::opt<MachineSchedRegistry::ScheduleDAGCtor, false,
11296f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick               RegisterPassParser<MachineSchedRegistry> >
11396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew TrickMachineSchedOpt("misched",
114d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick                cl::init(&useDefaultMachineSched), cl::Hidden,
11596f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick                cl::desc("Machine instruction scheduler to use"));
11696f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
117d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trickstatic MachineSchedRegistry
11817d35e57a585e869dc3084666abd17f173723735Andrew TrickDefaultSchedRegistry("default", "Use the target's default scheduler choice.",
119d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick                     useDefaultMachineSched);
120d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick
12117d35e57a585e869dc3084666abd17f173723735Andrew Trick/// Forward declare the standard machine scheduler. This will be used as the
122d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick/// default scheduler if the target does not set a default.
12317d35e57a585e869dc3084666abd17f173723735Andrew Trickstatic ScheduleDAGInstrs *createConvergingSched(MachineSchedContext *C);
124d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick
125cb058d51db44d47b57fc4705fea00209174d6577Andrew Trick/// Top-level MachineScheduler pass driver.
126cb058d51db44d47b57fc4705fea00209174d6577Andrew Trick///
127cb058d51db44d47b57fc4705fea00209174d6577Andrew Trick/// Visit blocks in function order. Divide each block into scheduling regions
12817d35e57a585e869dc3084666abd17f173723735Andrew Trick/// and visit them bottom-up. Visiting regions bottom-up is not required, but is
12917d35e57a585e869dc3084666abd17f173723735Andrew Trick/// consistent with the DAG builder, which traverses the interior of the
13017d35e57a585e869dc3084666abd17f173723735Andrew Trick/// scheduling regions bottom-up.
131cb058d51db44d47b57fc4705fea00209174d6577Andrew Trick///
132cb058d51db44d47b57fc4705fea00209174d6577Andrew Trick/// This design avoids exposing scheduling boundaries to the DAG builder,
13317d35e57a585e869dc3084666abd17f173723735Andrew Trick/// simplifying the DAG builder's support for "special" target instructions.
13417d35e57a585e869dc3084666abd17f173723735Andrew Trick/// At the same time the design allows target schedulers to operate across
135cb058d51db44d47b57fc4705fea00209174d6577Andrew Trick/// scheduling boundaries, for example to bundle the boudary instructions
136cb058d51db44d47b57fc4705fea00209174d6577Andrew Trick/// without reordering them. This creates complexity, because the target
137cb058d51db44d47b57fc4705fea00209174d6577Andrew Trick/// scheduler must update the RegionBegin and RegionEnd positions cached by
138cb058d51db44d47b57fc4705fea00209174d6577Andrew Trick/// ScheduleDAGInstrs whenever adding or removing instructions. A much simpler
139cb058d51db44d47b57fc4705fea00209174d6577Andrew Trick/// design would be to split blocks at scheduling boundaries, but LLVM has a
140cb058d51db44d47b57fc4705fea00209174d6577Andrew Trick/// general bias against block splitting purely for implementation simplicity.
141c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trickbool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
142c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  // Initialize the context of the pass.
143c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  MF = &mf;
144c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  MLI = &getAnalysis<MachineLoopInfo>();
145c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  MDT = &getAnalysis<MachineDominatorTree>();
146d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick  PassConfig = &getAnalysis<TargetPassConfig>();
147c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  AA = &getAnalysis<AliasAnalysis>();
148c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick
149c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  LIS = &getAnalysis<LiveIntervals>();
150c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
151c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick
152c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  // Select the scheduler, or set the default.
153d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick  MachineSchedRegistry::ScheduleDAGCtor Ctor = MachineSchedOpt;
154d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick  if (Ctor == useDefaultMachineSched) {
155d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick    // Get the default scheduler set by the target.
156d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick    Ctor = MachineSchedRegistry::getDefault();
157d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick    if (!Ctor) {
15817d35e57a585e869dc3084666abd17f173723735Andrew Trick      Ctor = createConvergingSched;
159d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick      MachineSchedRegistry::setDefault(Ctor);
160d04ec0c855176ebddd459c044bdd24f49938fae4Andrew Trick    }
161c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  }
162c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  // Instantiate the selected scheduler.
163c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  OwningPtr<ScheduleDAGInstrs> Scheduler(Ctor(this));
164c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick
165c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  // Visit all machine basic blocks.
166c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end();
167c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick       MBB != MBBEnd; ++MBB) {
168c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick
1691fabd9f85e8ac728c35cb63c70d8aac2c94c92a8Andrew Trick    Scheduler->startBlock(MBB);
1701fabd9f85e8ac728c35cb63c70d8aac2c94c92a8Andrew Trick
171c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick    // Break the block into scheduling regions [I, RegionEnd), and schedule each
172fe4d6df5c706c2ada666d95c25b8f460e30b1336Andrew Trick    // region as soon as it is discovered. RegionEnd points the the scheduling
173fe4d6df5c706c2ada666d95c25b8f460e30b1336Andrew Trick    // boundary at the bottom of the region. The DAG does not include RegionEnd,
174fe4d6df5c706c2ada666d95c25b8f460e30b1336Andrew Trick    // but the region does (i.e. the next RegionEnd is above the previous
175fe4d6df5c706c2ada666d95c25b8f460e30b1336Andrew Trick    // RegionBegin). If the current block has no terminator then RegionEnd ==
176fe4d6df5c706c2ada666d95c25b8f460e30b1336Andrew Trick    // MBB->end() for the bottom region.
177fe4d6df5c706c2ada666d95c25b8f460e30b1336Andrew Trick    //
178fe4d6df5c706c2ada666d95c25b8f460e30b1336Andrew Trick    // The Scheduler may insert instructions during either schedule() or
179fe4d6df5c706c2ada666d95c25b8f460e30b1336Andrew Trick    // exitRegion(), even for empty regions. So the local iterators 'I' and
180fe4d6df5c706c2ada666d95c25b8f460e30b1336Andrew Trick    // 'RegionEnd' are invalid across these calls.
181c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick    unsigned RemainingCount = MBB->size();
1827799eb40d43a1b0b0fef10bfcd7963f9cfe6c362Andrew Trick    for(MachineBasicBlock::iterator RegionEnd = MBB->end();
183fe4d6df5c706c2ada666d95c25b8f460e30b1336Andrew Trick        RegionEnd != MBB->begin(); RegionEnd = Scheduler->begin()) {
1841fabd9f85e8ac728c35cb63c70d8aac2c94c92a8Andrew Trick      // Avoid decrementing RegionEnd for blocks with no terminator.
1851fabd9f85e8ac728c35cb63c70d8aac2c94c92a8Andrew Trick      if (RegionEnd != MBB->end()
1861fabd9f85e8ac728c35cb63c70d8aac2c94c92a8Andrew Trick          || TII->isSchedulingBoundary(llvm::prior(RegionEnd), MBB, *MF)) {
1871fabd9f85e8ac728c35cb63c70d8aac2c94c92a8Andrew Trick        --RegionEnd;
1881fabd9f85e8ac728c35cb63c70d8aac2c94c92a8Andrew Trick        // Count the boundary instruction.
1891fabd9f85e8ac728c35cb63c70d8aac2c94c92a8Andrew Trick        --RemainingCount;
1901fabd9f85e8ac728c35cb63c70d8aac2c94c92a8Andrew Trick      }
1911fabd9f85e8ac728c35cb63c70d8aac2c94c92a8Andrew Trick
192c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      // The next region starts above the previous region. Look backward in the
193c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      // instruction stream until we find the nearest boundary.
194c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      MachineBasicBlock::iterator I = RegionEnd;
1957799eb40d43a1b0b0fef10bfcd7963f9cfe6c362Andrew Trick      for(;I != MBB->begin(); --I, --RemainingCount) {
196c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick        if (TII->isSchedulingBoundary(llvm::prior(I), MBB, *MF))
197c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick          break;
198c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      }
199c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      // Notify the scheduler of the region, even if we may skip scheduling
200c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      // it. Perhaps it still needs to be bundled.
201c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      Scheduler->enterRegion(MBB, I, RegionEnd, RemainingCount);
202c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick
203c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      // Skip empty scheduling regions (0 or 1 schedulable instructions).
204c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      if (I == RegionEnd || I == llvm::prior(RegionEnd)) {
205c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick        // Close the current region. Bundle the terminator if needed.
206fe4d6df5c706c2ada666d95c25b8f460e30b1336Andrew Trick        // This invalidates 'RegionEnd' and 'I'.
207c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick        Scheduler->exitRegion();
208c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick        continue;
209c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      }
210c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      DEBUG(dbgs() << "MachineScheduling " << MF->getFunction()->getName()
211c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick            << ":BB#" << MBB->getNumber() << "\n  From: " << *I << "    To: ";
212c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick            if (RegionEnd != MBB->end()) dbgs() << *RegionEnd;
213c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick            else dbgs() << "End";
214c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick            dbgs() << " Remaining: " << RemainingCount << "\n");
215c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick
216d24da97bbf86b87929ef8c57bdf3a009d48bfba7Andrew Trick      // Schedule a region: possibly reorder instructions.
217fe4d6df5c706c2ada666d95c25b8f460e30b1336Andrew Trick      // This invalidates 'RegionEnd' and 'I'.
218c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      Scheduler->schedule();
219d24da97bbf86b87929ef8c57bdf3a009d48bfba7Andrew Trick
220d24da97bbf86b87929ef8c57bdf3a009d48bfba7Andrew Trick      // Close the current region.
221c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      Scheduler->exitRegion();
222c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick
223c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      // Scheduling has invalidated the current iterator 'I'. Ask the
224c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      // scheduler for the top of it's scheduled region.
225c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick      RegionEnd = Scheduler->begin();
226c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick    }
227c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick    assert(RemainingCount == 0 && "Instruction count mismatch!");
228c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick    Scheduler->finishBlock();
229c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  }
230830da405fa32ab4f2a8378a658e1429a9ffd4d65Andrew Trick  Scheduler->finalizeSchedule();
231aad37f1925621cb1f9f2bb2c899b517bf1df344aAndrew Trick  DEBUG(LIS->print(dbgs()));
232c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  return true;
233c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick}
234c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick
235c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trickvoid MachineScheduler::print(raw_ostream &O, const Module* m) const {
236c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  // unimplemented
237c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick}
238c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick
2395edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick//===----------------------------------------------------------------------===//
24017d35e57a585e869dc3084666abd17f173723735Andrew Trick// MachineSchedStrategy - Interface to a machine scheduling algorithm.
24117d35e57a585e869dc3084666abd17f173723735Andrew Trick//===----------------------------------------------------------------------===//
24217d35e57a585e869dc3084666abd17f173723735Andrew Trick
24317d35e57a585e869dc3084666abd17f173723735Andrew Tricknamespace {
24417d35e57a585e869dc3084666abd17f173723735Andrew Trickclass ScheduleDAGMI;
24517d35e57a585e869dc3084666abd17f173723735Andrew Trick
24617d35e57a585e869dc3084666abd17f173723735Andrew Trick/// MachineSchedStrategy - Interface used by ScheduleDAGMI to drive the selected
24717d35e57a585e869dc3084666abd17f173723735Andrew Trick/// scheduling algorithm.
24817d35e57a585e869dc3084666abd17f173723735Andrew Trick///
24917d35e57a585e869dc3084666abd17f173723735Andrew Trick/// If this works well and targets wish to reuse ScheduleDAGMI, we may expose it
25017d35e57a585e869dc3084666abd17f173723735Andrew Trick/// in ScheduleDAGInstrs.h
25117d35e57a585e869dc3084666abd17f173723735Andrew Trickclass MachineSchedStrategy {
25217d35e57a585e869dc3084666abd17f173723735Andrew Trickpublic:
25317d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual ~MachineSchedStrategy() {}
25417d35e57a585e869dc3084666abd17f173723735Andrew Trick
25517d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// Initialize the strategy after building the DAG for a new region.
25617d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual void initialize(ScheduleDAGMI *DAG) = 0;
25717d35e57a585e869dc3084666abd17f173723735Andrew Trick
25817d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
25917d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// schedule the node at the top of the unscheduled region. Otherwise it will
26017d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// be scheduled at the bottom.
26117d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual SUnit *pickNode(bool &IsTopNode) = 0;
26217d35e57a585e869dc3084666abd17f173723735Andrew Trick
26317d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// When all predecessor dependencies have been resolved, free this node for
26417d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// top-down scheduling.
26517d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual void releaseTopNode(SUnit *SU) = 0;
26617d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// When all successor dependencies have been resolved, free this node for
26717d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// bottom-up scheduling.
26817d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual void releaseBottomNode(SUnit *SU) = 0;
26917d35e57a585e869dc3084666abd17f173723735Andrew Trick};
27017d35e57a585e869dc3084666abd17f173723735Andrew Trick} // namespace
27117d35e57a585e869dc3084666abd17f173723735Andrew Trick
27217d35e57a585e869dc3084666abd17f173723735Andrew Trick//===----------------------------------------------------------------------===//
27317d35e57a585e869dc3084666abd17f173723735Andrew Trick// ScheduleDAGMI - Base class for MachineInstr scheduling with LiveIntervals
27417d35e57a585e869dc3084666abd17f173723735Andrew Trick// preservation.
27517d35e57a585e869dc3084666abd17f173723735Andrew Trick//===----------------------------------------------------------------------===//
2765edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick
2775edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Tricknamespace {
27817d35e57a585e869dc3084666abd17f173723735Andrew Trick/// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that schedules
2795edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick/// machine instructions while updating LiveIntervals.
28017d35e57a585e869dc3084666abd17f173723735Andrew Trickclass ScheduleDAGMI : public ScheduleDAGInstrs {
281c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  AliasAnalysis *AA;
28217d35e57a585e869dc3084666abd17f173723735Andrew Trick  MachineSchedStrategy *SchedImpl;
28317d35e57a585e869dc3084666abd17f173723735Andrew Trick
28417d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// The top of the unscheduled zone.
28517d35e57a585e869dc3084666abd17f173723735Andrew Trick  MachineBasicBlock::iterator CurrentTop;
28617d35e57a585e869dc3084666abd17f173723735Andrew Trick
28717d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// The bottom of the unscheduled zone.
28817d35e57a585e869dc3084666abd17f173723735Andrew Trick  MachineBasicBlock::iterator CurrentBottom;
28923f1cbbd686513ae5defbd3afdf5e286befe8a76Lang Hames
29023f1cbbd686513ae5defbd3afdf5e286befe8a76Lang Hames  /// The number of instructions scheduled so far. Used to cut off the
29123f1cbbd686513ae5defbd3afdf5e286befe8a76Lang Hames  /// scheduler at the point determined by misched-cutoff.
29223f1cbbd686513ae5defbd3afdf5e286befe8a76Lang Hames  unsigned NumInstrsScheduled;
2935edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trickpublic:
29417d35e57a585e869dc3084666abd17f173723735Andrew Trick  ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S):
295c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick    ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
29623f1cbbd686513ae5defbd3afdf5e286befe8a76Lang Hames    AA(C->AA), SchedImpl(S), CurrentTop(), CurrentBottom(),
29723f1cbbd686513ae5defbd3afdf5e286befe8a76Lang Hames    NumInstrsScheduled(0) {}
298c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
29917d35e57a585e869dc3084666abd17f173723735Andrew Trick  ~ScheduleDAGMI() {
30017d35e57a585e869dc3084666abd17f173723735Andrew Trick    delete SchedImpl;
30117d35e57a585e869dc3084666abd17f173723735Andrew Trick  }
302c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
30317d35e57a585e869dc3084666abd17f173723735Andrew Trick  MachineBasicBlock::iterator top() const { return CurrentTop; }
30417d35e57a585e869dc3084666abd17f173723735Andrew Trick  MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
305c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
30617d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// Implement ScheduleDAGInstrs interface.
30717d35e57a585e869dc3084666abd17f173723735Andrew Trick  void schedule();
308c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
309c6cf11b41243967b16211848b50876aab47e86dfAndrew Trickprotected:
31017d35e57a585e869dc3084666abd17f173723735Andrew Trick  void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
3110b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick  bool checkSchedLimit();
31217d35e57a585e869dc3084666abd17f173723735Andrew Trick
313c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  void releaseSucc(SUnit *SU, SDep *SuccEdge);
314c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  void releaseSuccessors(SUnit *SU);
31517d35e57a585e869dc3084666abd17f173723735Andrew Trick  void releasePred(SUnit *SU, SDep *PredEdge);
31617d35e57a585e869dc3084666abd17f173723735Andrew Trick  void releasePredecessors(SUnit *SU);
3175edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick};
3185edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick} // namespace
3195edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick
320c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. When
321c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick/// NumPredsLeft reaches zero, release the successor node.
32217d35e57a585e869dc3084666abd17f173723735Andrew Trickvoid ScheduleDAGMI::releaseSucc(SUnit *SU, SDep *SuccEdge) {
323c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  SUnit *SuccSU = SuccEdge->getSUnit();
324c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
325c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick#ifndef NDEBUG
326c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  if (SuccSU->NumPredsLeft == 0) {
327c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick    dbgs() << "*** Scheduling failed! ***\n";
328c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick    SuccSU->dump(this);
329c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick    dbgs() << " has been released too many times!\n";
330c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick    llvm_unreachable(0);
331c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  }
332c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick#endif
333c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  --SuccSU->NumPredsLeft;
334c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU)
33517d35e57a585e869dc3084666abd17f173723735Andrew Trick    SchedImpl->releaseTopNode(SuccSU);
336c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick}
337c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
338c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick/// releaseSuccessors - Call releaseSucc on each of SU's successors.
33917d35e57a585e869dc3084666abd17f173723735Andrew Trickvoid ScheduleDAGMI::releaseSuccessors(SUnit *SU) {
340c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
341c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick       I != E; ++I) {
342c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick    releaseSucc(SU, &*I);
343c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  }
344c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick}
345c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
34617d35e57a585e869dc3084666abd17f173723735Andrew Trick/// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. When
34717d35e57a585e869dc3084666abd17f173723735Andrew Trick/// NumSuccsLeft reaches zero, release the predecessor node.
34817d35e57a585e869dc3084666abd17f173723735Andrew Trickvoid ScheduleDAGMI::releasePred(SUnit *SU, SDep *PredEdge) {
34917d35e57a585e869dc3084666abd17f173723735Andrew Trick  SUnit *PredSU = PredEdge->getSUnit();
35017d35e57a585e869dc3084666abd17f173723735Andrew Trick
35117d35e57a585e869dc3084666abd17f173723735Andrew Trick#ifndef NDEBUG
35217d35e57a585e869dc3084666abd17f173723735Andrew Trick  if (PredSU->NumSuccsLeft == 0) {
35317d35e57a585e869dc3084666abd17f173723735Andrew Trick    dbgs() << "*** Scheduling failed! ***\n";
35417d35e57a585e869dc3084666abd17f173723735Andrew Trick    PredSU->dump(this);
35517d35e57a585e869dc3084666abd17f173723735Andrew Trick    dbgs() << " has been released too many times!\n";
35617d35e57a585e869dc3084666abd17f173723735Andrew Trick    llvm_unreachable(0);
35717d35e57a585e869dc3084666abd17f173723735Andrew Trick  }
35817d35e57a585e869dc3084666abd17f173723735Andrew Trick#endif
35917d35e57a585e869dc3084666abd17f173723735Andrew Trick  --PredSU->NumSuccsLeft;
36017d35e57a585e869dc3084666abd17f173723735Andrew Trick  if (PredSU->NumSuccsLeft == 0 && PredSU != &EntrySU)
36117d35e57a585e869dc3084666abd17f173723735Andrew Trick    SchedImpl->releaseBottomNode(PredSU);
36217d35e57a585e869dc3084666abd17f173723735Andrew Trick}
36317d35e57a585e869dc3084666abd17f173723735Andrew Trick
36417d35e57a585e869dc3084666abd17f173723735Andrew Trick/// releasePredecessors - Call releasePred on each of SU's predecessors.
36517d35e57a585e869dc3084666abd17f173723735Andrew Trickvoid ScheduleDAGMI::releasePredecessors(SUnit *SU) {
36617d35e57a585e869dc3084666abd17f173723735Andrew Trick  for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
36717d35e57a585e869dc3084666abd17f173723735Andrew Trick       I != E; ++I) {
36817d35e57a585e869dc3084666abd17f173723735Andrew Trick    releasePred(SU, &*I);
36917d35e57a585e869dc3084666abd17f173723735Andrew Trick  }
37017d35e57a585e869dc3084666abd17f173723735Andrew Trick}
37117d35e57a585e869dc3084666abd17f173723735Andrew Trick
37217d35e57a585e869dc3084666abd17f173723735Andrew Trickvoid ScheduleDAGMI::moveInstruction(MachineInstr *MI,
37317d35e57a585e869dc3084666abd17f173723735Andrew Trick                                    MachineBasicBlock::iterator InsertPos) {
3741ce062fe567a08678d20149781c5e308e03d7d83Andrew Trick  // Fix RegionBegin if the first instruction moves down.
3751ce062fe567a08678d20149781c5e308e03d7d83Andrew Trick  if (&*RegionBegin == MI)
3761ce062fe567a08678d20149781c5e308e03d7d83Andrew Trick    RegionBegin = llvm::next(RegionBegin);
37717d35e57a585e869dc3084666abd17f173723735Andrew Trick  BB->splice(InsertPos, BB, MI);
37817d35e57a585e869dc3084666abd17f173723735Andrew Trick  LIS->handleMove(MI);
3791ce062fe567a08678d20149781c5e308e03d7d83Andrew Trick  // Fix RegionBegin if another instruction moves above the first instruction.
38017d35e57a585e869dc3084666abd17f173723735Andrew Trick  if (RegionBegin == InsertPos)
38117d35e57a585e869dc3084666abd17f173723735Andrew Trick    RegionBegin = MI;
38217d35e57a585e869dc3084666abd17f173723735Andrew Trick}
38317d35e57a585e869dc3084666abd17f173723735Andrew Trick
3840b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trickbool ScheduleDAGMI::checkSchedLimit() {
3850b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick#ifndef NDEBUG
3860b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick  if (NumInstrsScheduled == MISchedCutoff && MISchedCutoff != ~0U) {
3870b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick    CurrentTop = CurrentBottom;
3880b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick    return false;
3890b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick  }
3900b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick  ++NumInstrsScheduled;
3910b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick#endif
3920b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick  return true;
3930b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick}
3940b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick
39517d35e57a585e869dc3084666abd17f173723735Andrew Trick/// schedule - Called back from MachineScheduler::runOnMachineFunction
39617d35e57a585e869dc3084666abd17f173723735Andrew Trick/// after setting up the current scheduling region.
39717d35e57a585e869dc3084666abd17f173723735Andrew Trickvoid ScheduleDAGMI::schedule() {
398c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trick  buildSchedGraph(AA);
399c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
400c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  DEBUG(dbgs() << "********** MI Scheduling **********\n");
401c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
402c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick          SUnits[su].dumpAll(this));
403c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
4040df7f8821cc3ce26843b4fb63456cb4ccb7e4153Andrew Trick  if (ViewMISchedDAGs) viewGraph();
4050df7f8821cc3ce26843b4fb63456cb4ccb7e4153Andrew Trick
40617d35e57a585e869dc3084666abd17f173723735Andrew Trick  SchedImpl->initialize(this);
40717d35e57a585e869dc3084666abd17f173723735Andrew Trick
40817d35e57a585e869dc3084666abd17f173723735Andrew Trick  // Release edges from the special Entry node or to the special Exit node.
409c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  releaseSuccessors(&EntrySU);
41017d35e57a585e869dc3084666abd17f173723735Andrew Trick  releasePredecessors(&ExitSU);
411c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
412c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  // Release all DAG roots for scheduling.
413c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  for (std::vector<SUnit>::iterator I = SUnits.begin(), E = SUnits.end();
414c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick       I != E; ++I) {
41517d35e57a585e869dc3084666abd17f173723735Andrew Trick    // A SUnit is ready to top schedule if it has no predecessors.
416c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick    if (I->Preds.empty())
41717d35e57a585e869dc3084666abd17f173723735Andrew Trick      SchedImpl->releaseTopNode(&(*I));
41817d35e57a585e869dc3084666abd17f173723735Andrew Trick    // A SUnit is ready to bottom schedule if it has no successors.
41917d35e57a585e869dc3084666abd17f173723735Andrew Trick    if (I->Succs.empty())
42017d35e57a585e869dc3084666abd17f173723735Andrew Trick      SchedImpl->releaseBottomNode(&(*I));
421c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  }
422c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
42317d35e57a585e869dc3084666abd17f173723735Andrew Trick  CurrentTop = RegionBegin;
42417d35e57a585e869dc3084666abd17f173723735Andrew Trick  CurrentBottom = RegionEnd;
42517d35e57a585e869dc3084666abd17f173723735Andrew Trick  bool IsTopNode = false;
42617d35e57a585e869dc3084666abd17f173723735Andrew Trick  while (SUnit *SU = SchedImpl->pickNode(IsTopNode)) {
42717d35e57a585e869dc3084666abd17f173723735Andrew Trick    DEBUG(dbgs() << "*** " << (IsTopNode ? "Top" : "Bottom")
42817d35e57a585e869dc3084666abd17f173723735Andrew Trick          << " Scheduling Instruction:\n"; SU->dump(this));
4290b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick    if (!checkSchedLimit())
4300b0d899f917d4771c940e7fa92990d981822a6dbAndrew Trick      break;
431c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
432c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick    // Move the instruction to its new location in the instruction stream.
433c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick    MachineInstr *MI = SU->getInstr();
43417d35e57a585e869dc3084666abd17f173723735Andrew Trick
43517d35e57a585e869dc3084666abd17f173723735Andrew Trick    if (IsTopNode) {
43617d35e57a585e869dc3084666abd17f173723735Andrew Trick      assert(SU->isTopReady() && "node still has unscheduled dependencies");
43717d35e57a585e869dc3084666abd17f173723735Andrew Trick      if (&*CurrentTop == MI)
43817d35e57a585e869dc3084666abd17f173723735Andrew Trick        ++CurrentTop;
43917d35e57a585e869dc3084666abd17f173723735Andrew Trick      else
44017d35e57a585e869dc3084666abd17f173723735Andrew Trick        moveInstruction(MI, CurrentTop);
44117d35e57a585e869dc3084666abd17f173723735Andrew Trick      // Release dependent instructions for scheduling.
44217d35e57a585e869dc3084666abd17f173723735Andrew Trick      releaseSuccessors(SU);
44317d35e57a585e869dc3084666abd17f173723735Andrew Trick    }
444c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick    else {
44517d35e57a585e869dc3084666abd17f173723735Andrew Trick      assert(SU->isBottomReady() && "node still has unscheduled dependencies");
44617d35e57a585e869dc3084666abd17f173723735Andrew Trick      if (&*llvm::prior(CurrentBottom) == MI)
44717d35e57a585e869dc3084666abd17f173723735Andrew Trick        --CurrentBottom;
44817d35e57a585e869dc3084666abd17f173723735Andrew Trick      else {
4491ce062fe567a08678d20149781c5e308e03d7d83Andrew Trick        if (&*CurrentTop == MI)
4501ce062fe567a08678d20149781c5e308e03d7d83Andrew Trick          CurrentTop = llvm::next(CurrentTop);
45117d35e57a585e869dc3084666abd17f173723735Andrew Trick        moveInstruction(MI, CurrentBottom);
45217d35e57a585e869dc3084666abd17f173723735Andrew Trick        CurrentBottom = MI;
45317d35e57a585e869dc3084666abd17f173723735Andrew Trick      }
45417d35e57a585e869dc3084666abd17f173723735Andrew Trick      // Release dependent instructions for scheduling.
45517d35e57a585e869dc3084666abd17f173723735Andrew Trick      releasePredecessors(SU);
456c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick    }
45717d35e57a585e869dc3084666abd17f173723735Andrew Trick    SU->isScheduled = true;
458c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  }
45917d35e57a585e869dc3084666abd17f173723735Andrew Trick  assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone.");
460c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick}
461c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
4625edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick//===----------------------------------------------------------------------===//
46317d35e57a585e869dc3084666abd17f173723735Andrew Trick// ConvergingScheduler - Implementation of the standard MachineSchedStrategy.
46442b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick//===----------------------------------------------------------------------===//
46542b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick
46642b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Tricknamespace {
46717d35e57a585e869dc3084666abd17f173723735Andrew Trick/// ConvergingScheduler shrinks the unscheduled zone using heuristics to balance
46817d35e57a585e869dc3084666abd17f173723735Andrew Trick/// the schedule.
46917d35e57a585e869dc3084666abd17f173723735Andrew Trickclass ConvergingScheduler : public MachineSchedStrategy {
47017d35e57a585e869dc3084666abd17f173723735Andrew Trick  ScheduleDAGMI *DAG;
47117d35e57a585e869dc3084666abd17f173723735Andrew Trick
47217d35e57a585e869dc3084666abd17f173723735Andrew Trick  unsigned NumTopReady;
47317d35e57a585e869dc3084666abd17f173723735Andrew Trick  unsigned NumBottomReady;
47417d35e57a585e869dc3084666abd17f173723735Andrew Trick
47542b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trickpublic:
47617d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual void initialize(ScheduleDAGMI *dag) {
47717d35e57a585e869dc3084666abd17f173723735Andrew Trick    DAG = dag;
47842b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick
479689e0b42630f31f74d21041881b21412427924f7Benjamin Kramer    assert((!ForceTopDown || !ForceBottomUp) &&
48017d35e57a585e869dc3084666abd17f173723735Andrew Trick           "-misched-topdown incompatible with -misched-bottomup");
48117d35e57a585e869dc3084666abd17f173723735Andrew Trick  }
48242b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick
48317d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual SUnit *pickNode(bool &IsTopNode) {
48417d35e57a585e869dc3084666abd17f173723735Andrew Trick    if (DAG->top() == DAG->bottom())
48517d35e57a585e869dc3084666abd17f173723735Andrew Trick      return NULL;
48642b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick
48717d35e57a585e869dc3084666abd17f173723735Andrew Trick    // As an initial placeholder heuristic, schedule in the direction that has
48817d35e57a585e869dc3084666abd17f173723735Andrew Trick    // the fewest choices.
48917d35e57a585e869dc3084666abd17f173723735Andrew Trick    SUnit *SU;
49017d35e57a585e869dc3084666abd17f173723735Andrew Trick    if (ForceTopDown || (!ForceBottomUp && NumTopReady <= NumBottomReady)) {
49117d35e57a585e869dc3084666abd17f173723735Andrew Trick      SU = DAG->getSUnit(DAG->top());
49217d35e57a585e869dc3084666abd17f173723735Andrew Trick      IsTopNode = true;
49317d35e57a585e869dc3084666abd17f173723735Andrew Trick    }
49417d35e57a585e869dc3084666abd17f173723735Andrew Trick    else {
49517d35e57a585e869dc3084666abd17f173723735Andrew Trick      SU = DAG->getSUnit(llvm::prior(DAG->bottom()));
49617d35e57a585e869dc3084666abd17f173723735Andrew Trick      IsTopNode = false;
49717d35e57a585e869dc3084666abd17f173723735Andrew Trick    }
49817d35e57a585e869dc3084666abd17f173723735Andrew Trick    if (SU->isTopReady()) {
49917d35e57a585e869dc3084666abd17f173723735Andrew Trick      assert(NumTopReady > 0 && "bad ready count");
50017d35e57a585e869dc3084666abd17f173723735Andrew Trick      --NumTopReady;
50117d35e57a585e869dc3084666abd17f173723735Andrew Trick    }
50217d35e57a585e869dc3084666abd17f173723735Andrew Trick    if (SU->isBottomReady()) {
50317d35e57a585e869dc3084666abd17f173723735Andrew Trick      assert(NumBottomReady > 0 && "bad ready count");
50417d35e57a585e869dc3084666abd17f173723735Andrew Trick      --NumBottomReady;
50517d35e57a585e869dc3084666abd17f173723735Andrew Trick    }
50617d35e57a585e869dc3084666abd17f173723735Andrew Trick    return SU;
50717d35e57a585e869dc3084666abd17f173723735Andrew Trick  }
50842b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick
50917d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual void releaseTopNode(SUnit *SU) {
51017d35e57a585e869dc3084666abd17f173723735Andrew Trick    ++NumTopReady;
51117d35e57a585e869dc3084666abd17f173723735Andrew Trick  }
51217d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual void releaseBottomNode(SUnit *SU) {
51317d35e57a585e869dc3084666abd17f173723735Andrew Trick    ++NumBottomReady;
51417d35e57a585e869dc3084666abd17f173723735Andrew Trick  }
51517d35e57a585e869dc3084666abd17f173723735Andrew Trick};
51617d35e57a585e869dc3084666abd17f173723735Andrew Trick} // namespace
51742b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick
51817d35e57a585e869dc3084666abd17f173723735Andrew Trick/// Create the standard converging machine scheduler. This will be used as the
51917d35e57a585e869dc3084666abd17f173723735Andrew Trick/// default scheduler if the target does not set a default.
52017d35e57a585e869dc3084666abd17f173723735Andrew Trickstatic ScheduleDAGInstrs *createConvergingSched(MachineSchedContext *C) {
521689e0b42630f31f74d21041881b21412427924f7Benjamin Kramer  assert((!ForceTopDown || !ForceBottomUp) &&
52217d35e57a585e869dc3084666abd17f173723735Andrew Trick         "-misched-topdown incompatible with -misched-bottomup");
52317d35e57a585e869dc3084666abd17f173723735Andrew Trick  return new ScheduleDAGMI(C, new ConvergingScheduler());
52442b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick}
52517d35e57a585e869dc3084666abd17f173723735Andrew Trickstatic MachineSchedRegistry
52617d35e57a585e869dc3084666abd17f173723735Andrew TrickConvergingSchedRegistry("converge", "Standard converging scheduler.",
52717d35e57a585e869dc3084666abd17f173723735Andrew Trick                        createConvergingSched);
52842b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick
52942b7a71dc7381d1f38bf7b7201fc26dd80453364Andrew Trick//===----------------------------------------------------------------------===//
5305edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick// Machine Instruction Shuffler for Correctness Testing
5315edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick//===----------------------------------------------------------------------===//
5325edf2f03d525600c8c4aa0a2411666e647b8f154Andrew Trick
53396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick#ifndef NDEBUG
53496f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Tricknamespace {
53517d35e57a585e869dc3084666abd17f173723735Andrew Trick/// Apply a less-than relation on the node order, which corresponds to the
53617d35e57a585e869dc3084666abd17f173723735Andrew Trick/// instruction order prior to scheduling. IsReverse implements greater-than.
53717d35e57a585e869dc3084666abd17f173723735Andrew Tricktemplate<bool IsReverse>
53817d35e57a585e869dc3084666abd17f173723735Andrew Trickstruct SUnitOrder {
539c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  bool operator()(SUnit *A, SUnit *B) const {
54017d35e57a585e869dc3084666abd17f173723735Andrew Trick    if (IsReverse)
54117d35e57a585e869dc3084666abd17f173723735Andrew Trick      return A->NodeNum > B->NodeNum;
54217d35e57a585e869dc3084666abd17f173723735Andrew Trick    else
54317d35e57a585e869dc3084666abd17f173723735Andrew Trick      return A->NodeNum < B->NodeNum;
544c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  }
545c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick};
546c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
54796f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick/// Reorder instructions as much as possible.
54817d35e57a585e869dc3084666abd17f173723735Andrew Trickclass InstructionShuffler : public MachineSchedStrategy {
54917d35e57a585e869dc3084666abd17f173723735Andrew Trick  bool IsAlternating;
55017d35e57a585e869dc3084666abd17f173723735Andrew Trick  bool IsTopDown;
55117d35e57a585e869dc3084666abd17f173723735Andrew Trick
55217d35e57a585e869dc3084666abd17f173723735Andrew Trick  // Using a less-than relation (SUnitOrder<false>) for the TopQ priority
55317d35e57a585e869dc3084666abd17f173723735Andrew Trick  // gives nodes with a higher number higher priority causing the latest
55417d35e57a585e869dc3084666abd17f173723735Andrew Trick  // instructions to be scheduled first.
55517d35e57a585e869dc3084666abd17f173723735Andrew Trick  PriorityQueue<SUnit*, std::vector<SUnit*>, SUnitOrder<false> >
55617d35e57a585e869dc3084666abd17f173723735Andrew Trick    TopQ;
55717d35e57a585e869dc3084666abd17f173723735Andrew Trick  // When scheduling bottom-up, use greater-than as the queue priority.
55817d35e57a585e869dc3084666abd17f173723735Andrew Trick  PriorityQueue<SUnit*, std::vector<SUnit*>, SUnitOrder<true> >
55917d35e57a585e869dc3084666abd17f173723735Andrew Trick    BottomQ;
56096f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trickpublic:
56117d35e57a585e869dc3084666abd17f173723735Andrew Trick  InstructionShuffler(bool alternate, bool topdown)
56217d35e57a585e869dc3084666abd17f173723735Andrew Trick    : IsAlternating(alternate), IsTopDown(topdown) {}
56396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
56417d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual void initialize(ScheduleDAGMI *) {
56517d35e57a585e869dc3084666abd17f173723735Andrew Trick    TopQ.clear();
56617d35e57a585e869dc3084666abd17f173723735Andrew Trick    BottomQ.clear();
56717d35e57a585e869dc3084666abd17f173723735Andrew Trick  }
568c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
56917d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// Implement MachineSchedStrategy interface.
57017d35e57a585e869dc3084666abd17f173723735Andrew Trick  /// -----------------------------------------
57117d35e57a585e869dc3084666abd17f173723735Andrew Trick
57217d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual SUnit *pickNode(bool &IsTopNode) {
57317d35e57a585e869dc3084666abd17f173723735Andrew Trick    SUnit *SU;
57417d35e57a585e869dc3084666abd17f173723735Andrew Trick    if (IsTopDown) {
57517d35e57a585e869dc3084666abd17f173723735Andrew Trick      do {
57617d35e57a585e869dc3084666abd17f173723735Andrew Trick        if (TopQ.empty()) return NULL;
57717d35e57a585e869dc3084666abd17f173723735Andrew Trick        SU = TopQ.top();
57817d35e57a585e869dc3084666abd17f173723735Andrew Trick        TopQ.pop();
57917d35e57a585e869dc3084666abd17f173723735Andrew Trick      } while (SU->isScheduled);
58017d35e57a585e869dc3084666abd17f173723735Andrew Trick      IsTopNode = true;
58117d35e57a585e869dc3084666abd17f173723735Andrew Trick    }
58217d35e57a585e869dc3084666abd17f173723735Andrew Trick    else {
58317d35e57a585e869dc3084666abd17f173723735Andrew Trick      do {
58417d35e57a585e869dc3084666abd17f173723735Andrew Trick        if (BottomQ.empty()) return NULL;
58517d35e57a585e869dc3084666abd17f173723735Andrew Trick        SU = BottomQ.top();
58617d35e57a585e869dc3084666abd17f173723735Andrew Trick        BottomQ.pop();
58717d35e57a585e869dc3084666abd17f173723735Andrew Trick      } while (SU->isScheduled);
58817d35e57a585e869dc3084666abd17f173723735Andrew Trick      IsTopNode = false;
58917d35e57a585e869dc3084666abd17f173723735Andrew Trick    }
59017d35e57a585e869dc3084666abd17f173723735Andrew Trick    if (IsAlternating)
59117d35e57a585e869dc3084666abd17f173723735Andrew Trick      IsTopDown = !IsTopDown;
592c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick    return SU;
593c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick  }
594c6cf11b41243967b16211848b50876aab47e86dfAndrew Trick
59517d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual void releaseTopNode(SUnit *SU) {
59617d35e57a585e869dc3084666abd17f173723735Andrew Trick    TopQ.push(SU);
59717d35e57a585e869dc3084666abd17f173723735Andrew Trick  }
59817d35e57a585e869dc3084666abd17f173723735Andrew Trick  virtual void releaseBottomNode(SUnit *SU) {
59917d35e57a585e869dc3084666abd17f173723735Andrew Trick    BottomQ.push(SU);
60096f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick  }
60196f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick};
60296f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick} // namespace
60396f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick
604c174eaf9481e3f7a6695d4f19e62e2b6f005c4e9Andrew Trickstatic ScheduleDAGInstrs *createInstructionShuffler(MachineSchedContext *C) {
60517d35e57a585e869dc3084666abd17f173723735Andrew Trick  bool Alternate = !ForceTopDown && !ForceBottomUp;
60617d35e57a585e869dc3084666abd17f173723735Andrew Trick  bool TopDown = !ForceBottomUp;
607689e0b42630f31f74d21041881b21412427924f7Benjamin Kramer  assert((TopDown || !ForceTopDown) &&
60817d35e57a585e869dc3084666abd17f173723735Andrew Trick         "-misched-topdown incompatible with -misched-bottomup");
60917d35e57a585e869dc3084666abd17f173723735Andrew Trick  return new ScheduleDAGMI(C, new InstructionShuffler(Alternate, TopDown));
61096f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick}
61117d35e57a585e869dc3084666abd17f173723735Andrew Trickstatic MachineSchedRegistry ShufflerRegistry(
61217d35e57a585e869dc3084666abd17f173723735Andrew Trick  "shuffle", "Shuffle machine instructions alternating directions",
61317d35e57a585e869dc3084666abd17f173723735Andrew Trick  createInstructionShuffler);
61496f678f2d78ae9a2a8c99ca612bf59c056b36797Andrew Trick#endif // !NDEBUG
615