misched: implemented a framework for top-down or bottom-up scheduling.
[oota-llvm.git] / lib / CodeGen / MachineScheduler.cpp
1 //===- MachineScheduler.cpp - Machine Instruction Scheduler ---------------===//
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 // MachineScheduler schedules machine instructions after phi elimination. It
11 // preserves LiveIntervals so it can be invoked before register allocation.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "misched"
16
17 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
18 #include "llvm/CodeGen/MachineScheduler.h"
19 #include "llvm/CodeGen/Passes.h"
20 #include "llvm/CodeGen/ScheduleDAGInstrs.h"
21 #include "llvm/Analysis/AliasAnalysis.h"
22 #include "llvm/Target/TargetInstrInfo.h"
23 #include "llvm/Support/CommandLine.h"
24 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include "llvm/ADT/OwningPtr.h"
28 #include "llvm/ADT/PriorityQueue.h"
29
30 #include <queue>
31
32 using namespace llvm;
33
34 static cl::opt<bool> ForceTopDown("misched-topdown", cl::Hidden,
35                                   cl::desc("Force top-down list scheduling"));
36 static cl::opt<bool> ForceBottomUp("misched-bottomup", cl::Hidden,
37                                   cl::desc("Force bottom-up list scheduling"));
38
39 #ifndef NDEBUG
40 static cl::opt<bool> ViewMISchedDAGs("view-misched-dags", cl::Hidden,
41   cl::desc("Pop up a window to show MISched dags after they are processed"));
42 #else
43 static bool ViewMISchedDAGs = false;
44 #endif // NDEBUG
45
46 //===----------------------------------------------------------------------===//
47 // Machine Instruction Scheduling Pass and Registry
48 //===----------------------------------------------------------------------===//
49
50 namespace {
51 /// MachineScheduler runs after coalescing and before register allocation.
52 class MachineScheduler : public MachineSchedContext,
53                          public MachineFunctionPass {
54 public:
55   MachineScheduler();
56
57   virtual void getAnalysisUsage(AnalysisUsage &AU) const;
58
59   virtual void releaseMemory() {}
60
61   virtual bool runOnMachineFunction(MachineFunction&);
62
63   virtual void print(raw_ostream &O, const Module* = 0) const;
64
65   static char ID; // Class identification, replacement for typeinfo
66 };
67 } // namespace
68
69 char MachineScheduler::ID = 0;
70
71 char &llvm::MachineSchedulerID = MachineScheduler::ID;
72
73 INITIALIZE_PASS_BEGIN(MachineScheduler, "misched",
74                       "Machine Instruction Scheduler", false, false)
75 INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
76 INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
77 INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
78 INITIALIZE_PASS_END(MachineScheduler, "misched",
79                     "Machine Instruction Scheduler", false, false)
80
81 MachineScheduler::MachineScheduler()
82 : MachineFunctionPass(ID) {
83   initializeMachineSchedulerPass(*PassRegistry::getPassRegistry());
84 }
85
86 void MachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const {
87   AU.setPreservesCFG();
88   AU.addRequiredID(MachineDominatorsID);
89   AU.addRequired<MachineLoopInfo>();
90   AU.addRequired<AliasAnalysis>();
91   AU.addRequired<TargetPassConfig>();
92   AU.addRequired<SlotIndexes>();
93   AU.addPreserved<SlotIndexes>();
94   AU.addRequired<LiveIntervals>();
95   AU.addPreserved<LiveIntervals>();
96   MachineFunctionPass::getAnalysisUsage(AU);
97 }
98
99 MachinePassRegistry MachineSchedRegistry::Registry;
100
101 /// A dummy default scheduler factory indicates whether the scheduler
102 /// is overridden on the command line.
103 static ScheduleDAGInstrs *useDefaultMachineSched(MachineSchedContext *C) {
104   return 0;
105 }
106
107 /// MachineSchedOpt allows command line selection of the scheduler.
108 static cl::opt<MachineSchedRegistry::ScheduleDAGCtor, false,
109                RegisterPassParser<MachineSchedRegistry> >
110 MachineSchedOpt("misched",
111                 cl::init(&useDefaultMachineSched), cl::Hidden,
112                 cl::desc("Machine instruction scheduler to use"));
113
114 static MachineSchedRegistry
115 DefaultSchedRegistry("default", "Use the target's default scheduler choice.",
116                      useDefaultMachineSched);
117
118 /// Forward declare the standard machine scheduler. This will be used as the
119 /// default scheduler if the target does not set a default.
120 static ScheduleDAGInstrs *createConvergingSched(MachineSchedContext *C);
121
122 /// Top-level MachineScheduler pass driver.
123 ///
124 /// Visit blocks in function order. Divide each block into scheduling regions
125 /// and visit them bottom-up. Visiting regions bottom-up is not required, but is
126 /// consistent with the DAG builder, which traverses the interior of the
127 /// scheduling regions bottom-up.
128 ///
129 /// This design avoids exposing scheduling boundaries to the DAG builder,
130 /// simplifying the DAG builder's support for "special" target instructions.
131 /// At the same time the design allows target schedulers to operate across
132 /// scheduling boundaries, for example to bundle the boudary instructions
133 /// without reordering them. This creates complexity, because the target
134 /// scheduler must update the RegionBegin and RegionEnd positions cached by
135 /// ScheduleDAGInstrs whenever adding or removing instructions. A much simpler
136 /// design would be to split blocks at scheduling boundaries, but LLVM has a
137 /// general bias against block splitting purely for implementation simplicity.
138 bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
139   // Initialize the context of the pass.
140   MF = &mf;
141   MLI = &getAnalysis<MachineLoopInfo>();
142   MDT = &getAnalysis<MachineDominatorTree>();
143   PassConfig = &getAnalysis<TargetPassConfig>();
144   AA = &getAnalysis<AliasAnalysis>();
145
146   LIS = &getAnalysis<LiveIntervals>();
147   const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
148
149   // Select the scheduler, or set the default.
150   MachineSchedRegistry::ScheduleDAGCtor Ctor = MachineSchedOpt;
151   if (Ctor == useDefaultMachineSched) {
152     // Get the default scheduler set by the target.
153     Ctor = MachineSchedRegistry::getDefault();
154     if (!Ctor) {
155       Ctor = createConvergingSched;
156       MachineSchedRegistry::setDefault(Ctor);
157     }
158   }
159   // Instantiate the selected scheduler.
160   OwningPtr<ScheduleDAGInstrs> Scheduler(Ctor(this));
161
162   // Visit all machine basic blocks.
163   for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end();
164        MBB != MBBEnd; ++MBB) {
165
166     Scheduler->startBlock(MBB);
167
168     // Break the block into scheduling regions [I, RegionEnd), and schedule each
169     // region as soon as it is discovered. RegionEnd points the the scheduling
170     // boundary at the bottom of the region. The DAG does not include RegionEnd,
171     // but the region does (i.e. the next RegionEnd is above the previous
172     // RegionBegin). If the current block has no terminator then RegionEnd ==
173     // MBB->end() for the bottom region.
174     //
175     // The Scheduler may insert instructions during either schedule() or
176     // exitRegion(), even for empty regions. So the local iterators 'I' and
177     // 'RegionEnd' are invalid across these calls.
178     unsigned RemainingCount = MBB->size();
179     for(MachineBasicBlock::iterator RegionEnd = MBB->end();
180         RegionEnd != MBB->begin(); RegionEnd = Scheduler->begin()) {
181       // Avoid decrementing RegionEnd for blocks with no terminator.
182       if (RegionEnd != MBB->end()
183           || TII->isSchedulingBoundary(llvm::prior(RegionEnd), MBB, *MF)) {
184         --RegionEnd;
185         // Count the boundary instruction.
186         --RemainingCount;
187       }
188
189       // The next region starts above the previous region. Look backward in the
190       // instruction stream until we find the nearest boundary.
191       MachineBasicBlock::iterator I = RegionEnd;
192       for(;I != MBB->begin(); --I, --RemainingCount) {
193         if (TII->isSchedulingBoundary(llvm::prior(I), MBB, *MF))
194           break;
195       }
196       // Notify the scheduler of the region, even if we may skip scheduling
197       // it. Perhaps it still needs to be bundled.
198       Scheduler->enterRegion(MBB, I, RegionEnd, RemainingCount);
199
200       // Skip empty scheduling regions (0 or 1 schedulable instructions).
201       if (I == RegionEnd || I == llvm::prior(RegionEnd)) {
202         // Close the current region. Bundle the terminator if needed.
203         // This invalidates 'RegionEnd' and 'I'.
204         Scheduler->exitRegion();
205         continue;
206       }
207       DEBUG(dbgs() << "MachineScheduling " << MF->getFunction()->getName()
208             << ":BB#" << MBB->getNumber() << "\n  From: " << *I << "    To: ";
209             if (RegionEnd != MBB->end()) dbgs() << *RegionEnd;
210             else dbgs() << "End";
211             dbgs() << " Remaining: " << RemainingCount << "\n");
212
213       // Schedule a region: possibly reorder instructions.
214       // This invalidates 'RegionEnd' and 'I'.
215       Scheduler->schedule();
216
217       // Close the current region.
218       Scheduler->exitRegion();
219
220       // Scheduling has invalidated the current iterator 'I'. Ask the
221       // scheduler for the top of it's scheduled region.
222       RegionEnd = Scheduler->begin();
223     }
224     assert(RemainingCount == 0 && "Instruction count mismatch!");
225     Scheduler->finishBlock();
226   }
227   return true;
228 }
229
230 void MachineScheduler::print(raw_ostream &O, const Module* m) const {
231   // unimplemented
232 }
233
234 //===----------------------------------------------------------------------===//
235 // MachineSchedStrategy - Interface to a machine scheduling algorithm.
236 //===----------------------------------------------------------------------===//
237
238 namespace {
239 class ScheduleDAGMI;
240
241 /// MachineSchedStrategy - Interface used by ScheduleDAGMI to drive the selected
242 /// scheduling algorithm.
243 ///
244 /// If this works well and targets wish to reuse ScheduleDAGMI, we may expose it
245 /// in ScheduleDAGInstrs.h
246 class MachineSchedStrategy {
247 public:
248   virtual ~MachineSchedStrategy() {}
249
250   /// Initialize the strategy after building the DAG for a new region.
251   virtual void initialize(ScheduleDAGMI *DAG) = 0;
252
253   /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
254   /// schedule the node at the top of the unscheduled region. Otherwise it will
255   /// be scheduled at the bottom.
256   virtual SUnit *pickNode(bool &IsTopNode) = 0;
257
258   /// When all predecessor dependencies have been resolved, free this node for
259   /// top-down scheduling.
260   virtual void releaseTopNode(SUnit *SU) = 0;
261   /// When all successor dependencies have been resolved, free this node for
262   /// bottom-up scheduling.
263   virtual void releaseBottomNode(SUnit *SU) = 0;
264 };
265 } // namespace
266
267 //===----------------------------------------------------------------------===//
268 // ScheduleDAGMI - Base class for MachineInstr scheduling with LiveIntervals
269 // preservation.
270 //===----------------------------------------------------------------------===//
271
272 namespace {
273 /// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that schedules
274 /// machine instructions while updating LiveIntervals.
275 class ScheduleDAGMI : public ScheduleDAGInstrs {
276   AliasAnalysis *AA;
277   MachineSchedStrategy *SchedImpl;
278
279   /// The top of the unscheduled zone.
280   MachineBasicBlock::iterator CurrentTop;
281
282   /// The bottom of the unscheduled zone.
283   MachineBasicBlock::iterator CurrentBottom;
284 public:
285   ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S):
286     ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
287     AA(C->AA), SchedImpl(S), CurrentTop(), CurrentBottom() {}
288
289   ~ScheduleDAGMI() {
290     delete SchedImpl;
291   }
292
293   MachineBasicBlock::iterator top() const { return CurrentTop; }
294   MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
295
296   /// Implement ScheduleDAGInstrs interface.
297   void schedule();
298
299 protected:
300   void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
301
302   void releaseSucc(SUnit *SU, SDep *SuccEdge);
303   void releaseSuccessors(SUnit *SU);
304   void releasePred(SUnit *SU, SDep *PredEdge);
305   void releasePredecessors(SUnit *SU);
306 };
307 } // namespace
308
309 /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. When
310 /// NumPredsLeft reaches zero, release the successor node.
311 void ScheduleDAGMI::releaseSucc(SUnit *SU, SDep *SuccEdge) {
312   SUnit *SuccSU = SuccEdge->getSUnit();
313
314 #ifndef NDEBUG
315   if (SuccSU->NumPredsLeft == 0) {
316     dbgs() << "*** Scheduling failed! ***\n";
317     SuccSU->dump(this);
318     dbgs() << " has been released too many times!\n";
319     llvm_unreachable(0);
320   }
321 #endif
322   --SuccSU->NumPredsLeft;
323   if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU)
324     SchedImpl->releaseTopNode(SuccSU);
325 }
326
327 /// releaseSuccessors - Call releaseSucc on each of SU's successors.
328 void ScheduleDAGMI::releaseSuccessors(SUnit *SU) {
329   for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
330        I != E; ++I) {
331     releaseSucc(SU, &*I);
332   }
333 }
334
335 /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. When
336 /// NumSuccsLeft reaches zero, release the predecessor node.
337 void ScheduleDAGMI::releasePred(SUnit *SU, SDep *PredEdge) {
338   SUnit *PredSU = PredEdge->getSUnit();
339
340 #ifndef NDEBUG
341   if (PredSU->NumSuccsLeft == 0) {
342     dbgs() << "*** Scheduling failed! ***\n";
343     PredSU->dump(this);
344     dbgs() << " has been released too many times!\n";
345     llvm_unreachable(0);
346   }
347 #endif
348   --PredSU->NumSuccsLeft;
349   if (PredSU->NumSuccsLeft == 0 && PredSU != &EntrySU)
350     SchedImpl->releaseBottomNode(PredSU);
351 }
352
353 /// releasePredecessors - Call releasePred on each of SU's predecessors.
354 void ScheduleDAGMI::releasePredecessors(SUnit *SU) {
355   for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
356        I != E; ++I) {
357     releasePred(SU, &*I);
358   }
359 }
360
361 void ScheduleDAGMI::moveInstruction(MachineInstr *MI,
362                                     MachineBasicBlock::iterator InsertPos) {
363   BB->splice(InsertPos, BB, MI);
364   LIS->handleMove(MI);
365   if (RegionBegin == InsertPos)
366     RegionBegin = MI;
367 }
368
369 /// schedule - Called back from MachineScheduler::runOnMachineFunction
370 /// after setting up the current scheduling region.
371 void ScheduleDAGMI::schedule() {
372   buildSchedGraph(AA);
373
374   DEBUG(dbgs() << "********** MI Scheduling **********\n");
375   DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
376           SUnits[su].dumpAll(this));
377
378   if (ViewMISchedDAGs) viewGraph();
379
380   SchedImpl->initialize(this);
381
382   // Release edges from the special Entry node or to the special Exit node.
383   releaseSuccessors(&EntrySU);
384   releasePredecessors(&ExitSU);
385
386   // Release all DAG roots for scheduling.
387   for (std::vector<SUnit>::iterator I = SUnits.begin(), E = SUnits.end();
388        I != E; ++I) {
389     // A SUnit is ready to top schedule if it has no predecessors.
390     if (I->Preds.empty())
391       SchedImpl->releaseTopNode(&(*I));
392     // A SUnit is ready to bottom schedule if it has no successors.
393     if (I->Succs.empty())
394       SchedImpl->releaseBottomNode(&(*I));
395   }
396
397   CurrentTop = RegionBegin;
398   CurrentBottom = RegionEnd;
399   bool IsTopNode = false;
400   while (SUnit *SU = SchedImpl->pickNode(IsTopNode)) {
401     DEBUG(dbgs() << "*** " << (IsTopNode ? "Top" : "Bottom")
402           << " Scheduling Instruction:\n"; SU->dump(this));
403
404     // Move the instruction to its new location in the instruction stream.
405     MachineInstr *MI = SU->getInstr();
406
407     if (IsTopNode) {
408       assert(SU->isTopReady() && "node still has unscheduled dependencies");
409       if (&*CurrentTop == MI)
410         ++CurrentTop;
411       else
412         moveInstruction(MI, CurrentTop);
413       // Release dependent instructions for scheduling.
414       releaseSuccessors(SU);
415     }
416     else {
417       assert(SU->isBottomReady() && "node still has unscheduled dependencies");
418       if (&*llvm::prior(CurrentBottom) == MI)
419         --CurrentBottom;
420       else {
421         moveInstruction(MI, CurrentBottom);
422         CurrentBottom = MI;
423       }
424       // Release dependent instructions for scheduling.
425       releasePredecessors(SU);
426     }
427     SU->isScheduled = true;
428   }
429   assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone.");
430 }
431
432 //===----------------------------------------------------------------------===//
433 // ConvergingScheduler - Implementation of the standard MachineSchedStrategy.
434 //===----------------------------------------------------------------------===//
435
436 namespace {
437 /// ConvergingScheduler shrinks the unscheduled zone using heuristics to balance
438 /// the schedule.
439 class ConvergingScheduler : public MachineSchedStrategy {
440   ScheduleDAGMI *DAG;
441
442   unsigned NumTopReady;
443   unsigned NumBottomReady;
444
445 public:
446   virtual void initialize(ScheduleDAGMI *dag) {
447     DAG = dag;
448
449     assert(!ForceTopDown || !ForceBottomUp &&
450            "-misched-topdown incompatible with -misched-bottomup");
451   }
452
453   virtual SUnit *pickNode(bool &IsTopNode) {
454     if (DAG->top() == DAG->bottom())
455       return NULL;
456
457     // As an initial placeholder heuristic, schedule in the direction that has
458     // the fewest choices.
459     SUnit *SU;
460     if (ForceTopDown || (!ForceBottomUp && NumTopReady <= NumBottomReady)) {
461       SU = DAG->getSUnit(DAG->top());
462       IsTopNode = true;
463     }
464     else {
465       SU = DAG->getSUnit(llvm::prior(DAG->bottom()));
466       IsTopNode = false;
467     }
468     if (SU->isTopReady()) {
469       assert(NumTopReady > 0 && "bad ready count");
470       --NumTopReady;
471     }
472     if (SU->isBottomReady()) {
473       assert(NumBottomReady > 0 && "bad ready count");
474       --NumBottomReady;
475     }
476     return SU;
477   }
478
479   virtual void releaseTopNode(SUnit *SU) {
480     ++NumTopReady;
481   }
482   virtual void releaseBottomNode(SUnit *SU) {
483     ++NumBottomReady;
484   }
485 };
486 } // namespace
487
488 /// Create the standard converging machine scheduler. This will be used as the
489 /// default scheduler if the target does not set a default.
490 static ScheduleDAGInstrs *createConvergingSched(MachineSchedContext *C) {
491   assert(!ForceTopDown || !ForceBottomUp &&
492          "-misched-topdown incompatible with -misched-bottomup");
493   return new ScheduleDAGMI(C, new ConvergingScheduler());
494 }
495 static MachineSchedRegistry
496 ConvergingSchedRegistry("converge", "Standard converging scheduler.",
497                         createConvergingSched);
498
499 //===----------------------------------------------------------------------===//
500 // Machine Instruction Shuffler for Correctness Testing
501 //===----------------------------------------------------------------------===//
502
503 #ifndef NDEBUG
504 namespace {
505 /// Apply a less-than relation on the node order, which corresponds to the
506 /// instruction order prior to scheduling. IsReverse implements greater-than.
507 template<bool IsReverse>
508 struct SUnitOrder {
509   bool operator()(SUnit *A, SUnit *B) const {
510     if (IsReverse)
511       return A->NodeNum > B->NodeNum;
512     else
513       return A->NodeNum < B->NodeNum;
514   }
515 };
516
517 /// Reorder instructions as much as possible.
518 class InstructionShuffler : public MachineSchedStrategy {
519   bool IsAlternating;
520   bool IsTopDown;
521
522   // Using a less-than relation (SUnitOrder<false>) for the TopQ priority
523   // gives nodes with a higher number higher priority causing the latest
524   // instructions to be scheduled first.
525   PriorityQueue<SUnit*, std::vector<SUnit*>, SUnitOrder<false> >
526     TopQ;
527   // When scheduling bottom-up, use greater-than as the queue priority.
528   PriorityQueue<SUnit*, std::vector<SUnit*>, SUnitOrder<true> >
529     BottomQ;
530 public:
531   InstructionShuffler(bool alternate, bool topdown)
532     : IsAlternating(alternate), IsTopDown(topdown) {}
533
534   virtual void initialize(ScheduleDAGMI *) {
535     TopQ.clear();
536     BottomQ.clear();
537   }
538
539   /// Implement MachineSchedStrategy interface.
540   /// -----------------------------------------
541
542   virtual SUnit *pickNode(bool &IsTopNode) {
543     SUnit *SU;
544     if (IsTopDown) {
545       do {
546         if (TopQ.empty()) return NULL;
547         SU = TopQ.top();
548         TopQ.pop();
549       } while (SU->isScheduled);
550       IsTopNode = true;
551     }
552     else {
553       do {
554         if (BottomQ.empty()) return NULL;
555         SU = BottomQ.top();
556         BottomQ.pop();
557       } while (SU->isScheduled);
558       IsTopNode = false;
559     }
560     if (IsAlternating)
561       IsTopDown = !IsTopDown;
562     return SU;
563   }
564
565   virtual void releaseTopNode(SUnit *SU) {
566     TopQ.push(SU);
567   }
568   virtual void releaseBottomNode(SUnit *SU) {
569     BottomQ.push(SU);
570   }
571 };
572 } // namespace
573
574 static ScheduleDAGInstrs *createInstructionShuffler(MachineSchedContext *C) {
575   bool Alternate = !ForceTopDown && !ForceBottomUp;
576   bool TopDown = !ForceBottomUp;
577   assert(TopDown || !ForceTopDown &&
578          "-misched-topdown incompatible with -misched-bottomup");
579   return new ScheduleDAGMI(C, new InstructionShuffler(Alternate, TopDown));
580 }
581 static MachineSchedRegistry ShufflerRegistry(
582   "shuffle", "Shuffle machine instructions alternating directions",
583   createInstructionShuffler);
584 #endif // !NDEBUG