blob: 9985be6ba970e89065b75dbaf79ba07b0c1f677a [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"
18#include "LiveDebugVariables.h"
19#include "llvm/CodeGen/LiveIntervalAnalysis.h"
20#include "llvm/CodeGen/MachinePassRegistry.h"
21#include "llvm/CodeGen/Passes.h"
22#include "llvm/Analysis/AliasAnalysis.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
29using namespace llvm;
30
Andrew Trick5edf2f02012-01-14 02:17:06 +000031//===----------------------------------------------------------------------===//
32// Machine Instruction Scheduling Pass and Registry
33//===----------------------------------------------------------------------===//
34
Andrew Trick96f678f2012-01-13 06:30:30 +000035namespace {
36/// MachineSchedulerPass runs after coalescing and before register allocation.
37class MachineSchedulerPass : public MachineFunctionPass {
38public:
39 MachineFunction *MF;
Andrew Trick5edf2f02012-01-14 02:17:06 +000040 const TargetInstrInfo *TII;
Andrew Trick96f678f2012-01-13 06:30:30 +000041 const MachineLoopInfo *MLI;
42 const MachineDominatorTree *MDT;
43
44 MachineSchedulerPass();
45
46 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
47
48 virtual void releaseMemory() {}
49
50 virtual bool runOnMachineFunction(MachineFunction&);
51
52 virtual void print(raw_ostream &O, const Module* = 0) const;
53
54 static char ID; // Class identification, replacement for typeinfo
55};
56} // namespace
57
58char MachineSchedulerPass::ID = 0;
59
60char &llvm::MachineSchedulerPassID = MachineSchedulerPass::ID;
61
62INITIALIZE_PASS_BEGIN(MachineSchedulerPass, "misched",
63 "Machine Instruction Scheduler", false, false)
64INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
65INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
66INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
67INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
68INITIALIZE_PASS_DEPENDENCY(StrongPHIElimination)
69INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer)
70INITIALIZE_PASS_END(MachineSchedulerPass, "misched",
71 "Machine Instruction Scheduler", false, false)
72
73MachineSchedulerPass::MachineSchedulerPass()
74: MachineFunctionPass(ID), MF(0), MLI(0), MDT(0) {
75 initializeMachineSchedulerPassPass(*PassRegistry::getPassRegistry());
76}
77
78void MachineSchedulerPass::getAnalysisUsage(AnalysisUsage &AU) const {
79 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>();
88 AU.addRequired<LiveDebugVariables>();
89 AU.addPreserved<LiveDebugVariables>();
90 if (StrongPHIElim) {
91 AU.addRequiredID(StrongPHIEliminationID);
92 AU.addPreservedID(StrongPHIEliminationID);
93 }
94 AU.addRequiredID(RegisterCoalescerPassID);
95 AU.addPreservedID(RegisterCoalescerPassID);
96 MachineFunctionPass::getAnalysisUsage(AU);
97}
98
99namespace {
Andrew Trick96f678f2012-01-13 06:30:30 +0000100/// MachineSchedRegistry provides a selection of available machine instruction
101/// schedulers.
102class MachineSchedRegistry : public MachinePassRegistryNode {
103public:
104 typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineSchedulerPass *);
105
106 // RegisterPassParser requires a (misnamed) FunctionPassCtor type.
107 typedef ScheduleDAGCtor FunctionPassCtor;
108
109 static MachinePassRegistry Registry;
110
111 MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
112 : MachinePassRegistryNode(N, D, (MachinePassCtor)C) {
113 Registry.Add(this);
114 }
115 ~MachineSchedRegistry() { Registry.Remove(this); }
116
117 // Accessors.
118 //
119 MachineSchedRegistry *getNext() const {
120 return (MachineSchedRegistry *)MachinePassRegistryNode::getNext();
121 }
122 static MachineSchedRegistry *getList() {
123 return (MachineSchedRegistry *)Registry.getList();
124 }
125 static ScheduleDAGCtor getDefault() {
126 return (ScheduleDAGCtor)Registry.getDefault();
127 }
128 static void setDefault(ScheduleDAGCtor C) {
129 Registry.setDefault((MachinePassCtor)C);
130 }
131 static void setListener(MachinePassRegistryListener *L) {
132 Registry.setListener(L);
133 }
134};
135} // namespace
136
137MachinePassRegistry MachineSchedRegistry::Registry;
138
139static ScheduleDAGInstrs *createDefaultMachineSched(MachineSchedulerPass *P);
140
141/// MachineSchedOpt allows command line selection of the scheduler.
142static cl::opt<MachineSchedRegistry::ScheduleDAGCtor, false,
143 RegisterPassParser<MachineSchedRegistry> >
144MachineSchedOpt("misched",
145 cl::init(&createDefaultMachineSched), cl::Hidden,
146 cl::desc("Machine instruction scheduler to use"));
147
Andrew Trick5edf2f02012-01-14 02:17:06 +0000148//===----------------------------------------------------------------------===//
149// Machine Instruction Scheduling Implementation
150//===----------------------------------------------------------------------===//
151
152namespace {
153/// MachineScheduler is an implementation of ScheduleDAGInstrs that schedules
154/// machine instructions while updating LiveIntervals.
155class MachineScheduler : public ScheduleDAGInstrs {
156 MachineSchedulerPass *Pass;
157public:
158 MachineScheduler(MachineSchedulerPass *P):
159 ScheduleDAGInstrs(*P->MF, *P->MLI, *P->MDT), Pass(P) {}
160
161 /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
162 /// time to do some work.
163 virtual void Schedule();
164};
165} // namespace
166
Andrew Trick96f678f2012-01-13 06:30:30 +0000167static ScheduleDAGInstrs *createDefaultMachineSched(MachineSchedulerPass *P) {
168 return new MachineScheduler(P);
169}
170static MachineSchedRegistry
171SchedDefaultRegistry("default", "Activate the scheduler pass, "
172 "but don't reorder instructions",
173 createDefaultMachineSched);
174
175/// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
176/// time to do some work.
177void MachineScheduler::Schedule() {
178 DEBUG(dbgs() << "********** MI Scheduling **********\n");
179 DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
180 SUnits[su].dumpAll(this));
181 // TODO: Put interesting things here.
182}
183
184bool MachineSchedulerPass::runOnMachineFunction(MachineFunction &mf) {
185 // Initialize the context of the pass.
186 MF = &mf;
187 MLI = &getAnalysis<MachineLoopInfo>();
188 MDT = &getAnalysis<MachineDominatorTree>();
Andrew Trick5edf2f02012-01-14 02:17:06 +0000189 TII = MF->getTarget().getInstrInfo();
Andrew Trick96f678f2012-01-13 06:30:30 +0000190
191 // Select the scheduler, or set the default.
192 MachineSchedRegistry::ScheduleDAGCtor Ctor =
193 MachineSchedRegistry::getDefault();
194 if (!Ctor) {
195 Ctor = MachineSchedOpt;
196 MachineSchedRegistry::setDefault(Ctor);
197 }
198 // Instantiate the selected scheduler.
199 OwningPtr<ScheduleDAGInstrs> Scheduler(Ctor(this));
200
201 // Visit all machine basic blocks.
202 for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end();
203 MBB != MBBEnd; ++MBB) {
204
205 DEBUG(dbgs() << "MachineScheduling " << MF->getFunction()->getName()
206 << ":BB#" << MBB->getNumber() << "\n");
207
208 // Inform ScheduleDAGInstrs of the region being scheduler. It calls back
209 // to our Schedule() method.
210 Scheduler->Run(MBB, MBB->begin(), MBB->end(), MBB->size());
211 }
212 return true;
213}
214
215void MachineSchedulerPass::print(raw_ostream &O, const Module* m) const {
216 // unimplemented
217}
218
Andrew Trick5edf2f02012-01-14 02:17:06 +0000219//===----------------------------------------------------------------------===//
220// Machine Instruction Shuffler for Correctness Testing
221//===----------------------------------------------------------------------===//
222
Andrew Trick96f678f2012-01-13 06:30:30 +0000223#ifndef NDEBUG
224namespace {
225/// Reorder instructions as much as possible.
226class InstructionShuffler : public ScheduleDAGInstrs {
Andrew Trick5edf2f02012-01-14 02:17:06 +0000227 MachineSchedulerPass *Pass;
Andrew Trick96f678f2012-01-13 06:30:30 +0000228public:
Andrew Trick5edf2f02012-01-14 02:17:06 +0000229 InstructionShuffler(MachineSchedulerPass *P):
230 ScheduleDAGInstrs(*P->MF, *P->MLI, *P->MDT), Pass(P) {}
Andrew Trick96f678f2012-01-13 06:30:30 +0000231
232 /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
233 /// time to do some work.
234 virtual void Schedule() {
235 llvm_unreachable("unimplemented");
236 }
237};
238} // namespace
239
240static ScheduleDAGInstrs *createInstructionShuffler(MachineSchedulerPass *P) {
241 return new InstructionShuffler(P);
242}
243static MachineSchedRegistry ShufflerRegistry("shuffle",
244 "Shuffle machine instructions",
245 createInstructionShuffler);
246#endif // !NDEBUG