blob: 6034c9082c4d482040a60bfc0a2bad13ffc54da3 [file] [log] [blame]
Andrew Trick96f678f2012-01-13 06:30:30 +00001//===- 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 "ScheduleDAGInstrs.h"
Andrew Trick96f678f2012-01-13 06:30:30 +000018#include "llvm/CodeGen/LiveIntervalAnalysis.h"
19#include "llvm/CodeGen/MachinePassRegistry.h"
20#include "llvm/CodeGen/Passes.h"
21#include "llvm/Analysis/AliasAnalysis.h"
Andrew Tricke9ef4ed2012-01-14 02:17:09 +000022#include "llvm/Target/TargetInstrInfo.h"
Andrew Trick96f678f2012-01-13 06:30:30 +000023#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
Andrew Trickc6cf11b2012-01-17 06:55:07 +000029#include <queue>
30
Andrew Trick96f678f2012-01-13 06:30:30 +000031using namespace llvm;
32
Andrew Trick5edf2f02012-01-14 02:17:06 +000033//===----------------------------------------------------------------------===//
34// Machine Instruction Scheduling Pass and Registry
35//===----------------------------------------------------------------------===//
36
Andrew Trick96f678f2012-01-13 06:30:30 +000037namespace {
Andrew Trick42b7a712012-01-17 06:55:03 +000038/// MachineScheduler runs after coalescing and before register allocation.
39class MachineScheduler : public MachineFunctionPass {
Andrew Trick96f678f2012-01-13 06:30:30 +000040public:
41 MachineFunction *MF;
Andrew Trick5edf2f02012-01-14 02:17:06 +000042 const TargetInstrInfo *TII;
Andrew Trick96f678f2012-01-13 06:30:30 +000043 const MachineLoopInfo *MLI;
44 const MachineDominatorTree *MDT;
Lang Hames907cc8f2012-01-27 22:36:19 +000045 LiveIntervals *LIS;
Andrew Trick96f678f2012-01-13 06:30:30 +000046
Andrew Trick42b7a712012-01-17 06:55:03 +000047 MachineScheduler();
Andrew Trick96f678f2012-01-13 06:30:30 +000048
49 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
50
51 virtual void releaseMemory() {}
52
53 virtual bool runOnMachineFunction(MachineFunction&);
54
55 virtual void print(raw_ostream &O, const Module* = 0) const;
56
57 static char ID; // Class identification, replacement for typeinfo
58};
59} // namespace
60
Andrew Trick42b7a712012-01-17 06:55:03 +000061char MachineScheduler::ID = 0;
Andrew Trick96f678f2012-01-13 06:30:30 +000062
Andrew Trick42b7a712012-01-17 06:55:03 +000063char &llvm::MachineSchedulerID = MachineScheduler::ID;
Andrew Trick96f678f2012-01-13 06:30:30 +000064
Andrew Trick42b7a712012-01-17 06:55:03 +000065INITIALIZE_PASS_BEGIN(MachineScheduler, "misched",
Andrew Trick96f678f2012-01-13 06:30:30 +000066 "Machine Instruction Scheduler", false, false)
67INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
68INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
69INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
Andrew Trick42b7a712012-01-17 06:55:03 +000070INITIALIZE_PASS_END(MachineScheduler, "misched",
Andrew Trick96f678f2012-01-13 06:30:30 +000071 "Machine Instruction Scheduler", false, false)
72
Andrew Trick42b7a712012-01-17 06:55:03 +000073MachineScheduler::MachineScheduler()
Andrew Trick96f678f2012-01-13 06:30:30 +000074: MachineFunctionPass(ID), MF(0), MLI(0), MDT(0) {
Andrew Trick42b7a712012-01-17 06:55:03 +000075 initializeMachineSchedulerPass(*PassRegistry::getPassRegistry());
Andrew Trick96f678f2012-01-13 06:30:30 +000076}
77
Andrew Trick42b7a712012-01-17 06:55:03 +000078void MachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const {
Andrew Trick96f678f2012-01-13 06:30:30 +000079 AU.setPreservesCFG();
80 AU.addRequiredID(MachineDominatorsID);
81 AU.addRequired<MachineLoopInfo>();
82 AU.addRequired<AliasAnalysis>();
83 AU.addPreserved<AliasAnalysis>();
84 AU.addRequired<SlotIndexes>();
85 AU.addPreserved<SlotIndexes>();
86 AU.addRequired<LiveIntervals>();
87 AU.addPreserved<LiveIntervals>();
Andrew Trick96f678f2012-01-13 06:30:30 +000088 MachineFunctionPass::getAnalysisUsage(AU);
89}
90
91namespace {
Andrew Trick96f678f2012-01-13 06:30:30 +000092/// MachineSchedRegistry provides a selection of available machine instruction
93/// schedulers.
94class MachineSchedRegistry : public MachinePassRegistryNode {
95public:
Andrew Trick42b7a712012-01-17 06:55:03 +000096 typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineScheduler *);
Andrew Trick96f678f2012-01-13 06:30:30 +000097
98 // RegisterPassParser requires a (misnamed) FunctionPassCtor type.
99 typedef ScheduleDAGCtor FunctionPassCtor;
100
101 static MachinePassRegistry Registry;
102
103 MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
104 : MachinePassRegistryNode(N, D, (MachinePassCtor)C) {
105 Registry.Add(this);
106 }
107 ~MachineSchedRegistry() { Registry.Remove(this); }
108
109 // Accessors.
110 //
111 MachineSchedRegistry *getNext() const {
112 return (MachineSchedRegistry *)MachinePassRegistryNode::getNext();
113 }
114 static MachineSchedRegistry *getList() {
115 return (MachineSchedRegistry *)Registry.getList();
116 }
117 static ScheduleDAGCtor getDefault() {
118 return (ScheduleDAGCtor)Registry.getDefault();
119 }
120 static void setDefault(ScheduleDAGCtor C) {
121 Registry.setDefault((MachinePassCtor)C);
122 }
123 static void setListener(MachinePassRegistryListener *L) {
124 Registry.setListener(L);
125 }
126};
127} // namespace
128
129MachinePassRegistry MachineSchedRegistry::Registry;
130
Andrew Trick42b7a712012-01-17 06:55:03 +0000131static ScheduleDAGInstrs *createDefaultMachineSched(MachineScheduler *P);
Andrew Trick96f678f2012-01-13 06:30:30 +0000132
133/// MachineSchedOpt allows command line selection of the scheduler.
134static cl::opt<MachineSchedRegistry::ScheduleDAGCtor, false,
135 RegisterPassParser<MachineSchedRegistry> >
136MachineSchedOpt("misched",
137 cl::init(&createDefaultMachineSched), cl::Hidden,
138 cl::desc("Machine instruction scheduler to use"));
139
Andrew Trick5edf2f02012-01-14 02:17:06 +0000140//===----------------------------------------------------------------------===//
Andrew Trick42b7a712012-01-17 06:55:03 +0000141// Machine Instruction Scheduling Common Implementation
Andrew Trick5edf2f02012-01-14 02:17:06 +0000142//===----------------------------------------------------------------------===//
143
144namespace {
Andrew Trick78b29612012-02-09 00:40:52 +0000145/// ScheduleTopDownLive is an implementation of ScheduleDAGInstrs that schedules
Andrew Trick5edf2f02012-01-14 02:17:06 +0000146/// machine instructions while updating LiveIntervals.
Andrew Trick42b7a712012-01-17 06:55:03 +0000147class ScheduleTopDownLive : public ScheduleDAGInstrs {
148protected:
149 MachineScheduler *Pass;
Andrew Trick5edf2f02012-01-14 02:17:06 +0000150public:
Andrew Trick42b7a712012-01-17 06:55:03 +0000151 ScheduleTopDownLive(MachineScheduler *P):
Andrew Trick5e920d72012-01-14 02:17:12 +0000152 ScheduleDAGInstrs(*P->MF, *P->MLI, *P->MDT, /*IsPostRA=*/false), Pass(P) {}
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000153
154 /// ScheduleDAGInstrs callback.
155 void Schedule();
156
157 /// Interface implemented by the selected top-down liveinterval scheduler.
158 ///
159 /// Pick the next node to schedule, or return NULL.
160 virtual SUnit *pickNode() = 0;
161
162 /// When all preceeding dependencies have been resolved, free this node for
163 /// scheduling.
164 virtual void releaseNode(SUnit *SU) = 0;
165
166protected:
167 void releaseSucc(SUnit *SU, SDep *SuccEdge);
168 void releaseSuccessors(SUnit *SU);
Andrew Trick5edf2f02012-01-14 02:17:06 +0000169};
170} // namespace
171
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000172/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. When
173/// NumPredsLeft reaches zero, release the successor node.
174void ScheduleTopDownLive::releaseSucc(SUnit *SU, SDep *SuccEdge) {
175 SUnit *SuccSU = SuccEdge->getSUnit();
176
177#ifndef NDEBUG
178 if (SuccSU->NumPredsLeft == 0) {
179 dbgs() << "*** Scheduling failed! ***\n";
180 SuccSU->dump(this);
181 dbgs() << " has been released too many times!\n";
182 llvm_unreachable(0);
183 }
184#endif
185 --SuccSU->NumPredsLeft;
186 if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU)
187 releaseNode(SuccSU);
188}
189
190/// releaseSuccessors - Call releaseSucc on each of SU's successors.
191void ScheduleTopDownLive::releaseSuccessors(SUnit *SU) {
192 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
193 I != E; ++I) {
194 releaseSucc(SU, &*I);
195 }
196}
197
198/// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
199/// time to do some work.
200void ScheduleTopDownLive::Schedule() {
201 BuildSchedGraph(&Pass->getAnalysis<AliasAnalysis>());
202
203 DEBUG(dbgs() << "********** MI Scheduling **********\n");
204 DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
205 SUnits[su].dumpAll(this));
206
207 // Release any successors of the special Entry node. It is currently unused,
208 // but we keep up appearances.
209 releaseSuccessors(&EntrySU);
210
211 // Release all DAG roots for scheduling.
212 for (std::vector<SUnit>::iterator I = SUnits.begin(), E = SUnits.end();
213 I != E; ++I) {
214 // A SUnit is ready to schedule if it has no predecessors.
215 if (I->Preds.empty())
216 releaseNode(&(*I));
217 }
218
219 InsertPos = Begin;
220 while (SUnit *SU = pickNode()) {
221 DEBUG(dbgs() << "*** Scheduling Instruction:\n"; SU->dump(this));
222
223 // Move the instruction to its new location in the instruction stream.
224 MachineInstr *MI = SU->getInstr();
225 if (&*InsertPos == MI)
226 ++InsertPos;
227 else {
Lang Hamesda7984f2012-02-15 01:23:52 +0000228 BB->splice(InsertPos, BB, MI);
229 Pass->LIS->handleMove(MI);
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000230 if (Begin == InsertPos)
231 Begin = MI;
232 }
233
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000234 // Release dependent instructions for scheduling.
235 releaseSuccessors(SU);
236 }
237}
238
Andrew Trick42b7a712012-01-17 06:55:03 +0000239bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
Andrew Trick96f678f2012-01-13 06:30:30 +0000240 // Initialize the context of the pass.
241 MF = &mf;
242 MLI = &getAnalysis<MachineLoopInfo>();
243 MDT = &getAnalysis<MachineDominatorTree>();
Lang Hames907cc8f2012-01-27 22:36:19 +0000244 LIS = &getAnalysis<LiveIntervals>();
Andrew Trick5edf2f02012-01-14 02:17:06 +0000245 TII = MF->getTarget().getInstrInfo();
Andrew Trick96f678f2012-01-13 06:30:30 +0000246
247 // Select the scheduler, or set the default.
248 MachineSchedRegistry::ScheduleDAGCtor Ctor =
249 MachineSchedRegistry::getDefault();
250 if (!Ctor) {
251 Ctor = MachineSchedOpt;
252 MachineSchedRegistry::setDefault(Ctor);
253 }
254 // Instantiate the selected scheduler.
255 OwningPtr<ScheduleDAGInstrs> Scheduler(Ctor(this));
256
257 // Visit all machine basic blocks.
258 for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end();
259 MBB != MBBEnd; ++MBB) {
260
Andrew Tricke9ef4ed2012-01-14 02:17:09 +0000261 // Break the block into scheduling regions [I, RegionEnd), and schedule each
262 // region as soon as it is discovered.
263 unsigned RemainingCount = MBB->size();
264 for(MachineBasicBlock::iterator RegionEnd = MBB->end();
265 RegionEnd != MBB->begin();) {
266 // The next region starts above the previous region. Look backward in the
267 // instruction stream until we find the nearest boundary.
268 MachineBasicBlock::iterator I = RegionEnd;
Andrew Trick3c58ba82012-01-14 02:17:18 +0000269 for(;I != MBB->begin(); --I, --RemainingCount) {
Andrew Tricke9ef4ed2012-01-14 02:17:09 +0000270 if (TII->isSchedulingBoundary(llvm::prior(I), MBB, *MF))
271 break;
272 }
Andrew Trick3c58ba82012-01-14 02:17:18 +0000273 if (I == RegionEnd) {
274 // Skip empty scheduling regions.
Andrew Tricke9ef4ed2012-01-14 02:17:09 +0000275 RegionEnd = llvm::prior(RegionEnd);
Andrew Trick3c58ba82012-01-14 02:17:18 +0000276 --RemainingCount;
Andrew Tricke9ef4ed2012-01-14 02:17:09 +0000277 continue;
278 }
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000279 // Skip regions with one instruction.
280 if (I == llvm::prior(RegionEnd)) {
281 RegionEnd = llvm::prior(RegionEnd);
282 continue;
Andrew Trick3c58ba82012-01-14 02:17:18 +0000283 }
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000284 DEBUG(dbgs() << "MachineScheduling " << MF->getFunction()->getName()
Andrew Trick291411c2012-02-08 02:17:21 +0000285 << ":BB#" << MBB->getNumber() << "\n From: " << *I << " To: ";
286 if (RegionEnd != MBB->end()) dbgs() << *RegionEnd;
287 else dbgs() << "End";
288 dbgs() << " Remaining: " << RemainingCount << "\n");
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000289
290 // Inform ScheduleDAGInstrs of the region being scheduled. It calls back
291 // to our Schedule() method.
292 Scheduler->Run(MBB, I, RegionEnd, MBB->size());
293 RegionEnd = Scheduler->Begin;
Andrew Tricke9ef4ed2012-01-14 02:17:09 +0000294 }
295 assert(RemainingCount == 0 && "Instruction count mismatch!");
Andrew Trick96f678f2012-01-13 06:30:30 +0000296 }
297 return true;
298}
299
Andrew Trick42b7a712012-01-17 06:55:03 +0000300void MachineScheduler::print(raw_ostream &O, const Module* m) const {
Andrew Trick96f678f2012-01-13 06:30:30 +0000301 // unimplemented
302}
303
Andrew Trick5edf2f02012-01-14 02:17:06 +0000304//===----------------------------------------------------------------------===//
Andrew Trick42b7a712012-01-17 06:55:03 +0000305// Placeholder for extending the machine instruction scheduler.
306//===----------------------------------------------------------------------===//
307
308namespace {
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000309class DefaultMachineScheduler : public ScheduleDAGInstrs {
310 MachineScheduler *Pass;
Andrew Trick42b7a712012-01-17 06:55:03 +0000311public:
312 DefaultMachineScheduler(MachineScheduler *P):
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000313 ScheduleDAGInstrs(*P->MF, *P->MLI, *P->MDT, /*IsPostRA=*/false), Pass(P) {}
Andrew Trick42b7a712012-01-17 06:55:03 +0000314
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000315 /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
316 /// time to do some work.
Andrew Trick42b7a712012-01-17 06:55:03 +0000317 void Schedule();
318};
319} // namespace
320
321static ScheduleDAGInstrs *createDefaultMachineSched(MachineScheduler *P) {
322 return new DefaultMachineScheduler(P);
323}
324static MachineSchedRegistry
325SchedDefaultRegistry("default", "Activate the scheduler pass, "
326 "but don't reorder instructions",
327 createDefaultMachineSched);
328
329
330/// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
331/// time to do some work.
332void DefaultMachineScheduler::Schedule() {
333 BuildSchedGraph(&Pass->getAnalysis<AliasAnalysis>());
334
335 DEBUG(dbgs() << "********** MI Scheduling **********\n");
336 DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
337 SUnits[su].dumpAll(this));
338
339 // TODO: Put interesting things here.
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000340 //
341 // When this is fully implemented, it will become a subclass of
342 // ScheduleTopDownLive. So this driver will disappear.
Andrew Trick42b7a712012-01-17 06:55:03 +0000343}
344
345//===----------------------------------------------------------------------===//
Andrew Trick5edf2f02012-01-14 02:17:06 +0000346// Machine Instruction Shuffler for Correctness Testing
347//===----------------------------------------------------------------------===//
348
Andrew Trick96f678f2012-01-13 06:30:30 +0000349#ifndef NDEBUG
350namespace {
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000351// Nodes with a higher number have lower priority. This way we attempt to
352// schedule the latest instructions earliest.
353//
354// TODO: Relies on the property of the BuildSchedGraph that results in SUnits
355// being ordered in sequence bottom-up. This will be formalized, probably be
356// constructing SUnits in a prepass.
357struct ShuffleSUnitOrder {
358 bool operator()(SUnit *A, SUnit *B) const {
359 return A->NodeNum > B->NodeNum;
360 }
361};
362
Andrew Trick96f678f2012-01-13 06:30:30 +0000363/// Reorder instructions as much as possible.
Andrew Trick42b7a712012-01-17 06:55:03 +0000364class InstructionShuffler : public ScheduleTopDownLive {
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000365 std::priority_queue<SUnit*, std::vector<SUnit*>, ShuffleSUnitOrder> Queue;
Andrew Trick96f678f2012-01-13 06:30:30 +0000366public:
Andrew Trick42b7a712012-01-17 06:55:03 +0000367 InstructionShuffler(MachineScheduler *P):
368 ScheduleTopDownLive(P) {}
Andrew Trick96f678f2012-01-13 06:30:30 +0000369
Andrew Trickc6cf11b2012-01-17 06:55:07 +0000370 /// ScheduleTopDownLive Interface
371
372 virtual SUnit *pickNode() {
373 if (Queue.empty()) return NULL;
374 SUnit *SU = Queue.top();
375 Queue.pop();
376 return SU;
377 }
378
379 virtual void releaseNode(SUnit *SU) {
380 Queue.push(SU);
Andrew Trick96f678f2012-01-13 06:30:30 +0000381 }
382};
383} // namespace
384
Andrew Trick42b7a712012-01-17 06:55:03 +0000385static ScheduleDAGInstrs *createInstructionShuffler(MachineScheduler *P) {
Andrew Trick96f678f2012-01-13 06:30:30 +0000386 return new InstructionShuffler(P);
387}
388static MachineSchedRegistry ShufflerRegistry("shuffle",
389 "Shuffle machine instructions",
390 createInstructionShuffler);
391#endif // !NDEBUG