blob: 910732538e97800b516f2000e5152221dd33f967 [file] [log] [blame]
Lang Hamese2b201b2009-05-18 19:03:16 +00001//===-- llvm/CodeGen/Spiller.cpp - Spiller -------------------------------===//
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#define DEBUG_TYPE "spiller"
11
12#include "Spiller.h"
13#include "VirtRegMap.h"
14#include "llvm/CodeGen/LiveIntervalAnalysis.h"
Lang Hamesf41538d2009-06-02 16:53:25 +000015#include "llvm/CodeGen/LiveStackAnalysis.h"
Bill Wendlingc75e7d22009-08-22 20:54:03 +000016#include "llvm/CodeGen/MachineFrameInfo.h"
Lang Hamese2b201b2009-05-18 19:03:16 +000017#include "llvm/CodeGen/MachineFunction.h"
18#include "llvm/CodeGen/MachineRegisterInfo.h"
Lang Hamese2b201b2009-05-18 19:03:16 +000019#include "llvm/Target/TargetMachine.h"
20#include "llvm/Target/TargetInstrInfo.h"
21#include "llvm/Support/Debug.h"
Bill Wendlingc75e7d22009-08-22 20:54:03 +000022#include "llvm/Support/raw_ostream.h"
Lang Hamese2b201b2009-05-18 19:03:16 +000023
Lang Hamese2b201b2009-05-18 19:03:16 +000024using namespace llvm;
25
26Spiller::~Spiller() {}
27
28namespace {
29
Lang Hamesf41538d2009-06-02 16:53:25 +000030/// Utility class for spillers.
31class SpillerBase : public Spiller {
32protected:
33
34 MachineFunction *mf;
35 LiveIntervals *lis;
36 LiveStacks *ls;
37 MachineFrameInfo *mfi;
38 MachineRegisterInfo *mri;
39 const TargetInstrInfo *tii;
40 VirtRegMap *vrm;
41
42 /// Construct a spiller base.
Lang Hames10382fb2009-06-19 02:17:53 +000043 SpillerBase(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls,
44 VirtRegMap *vrm) :
Lang Hamesf41538d2009-06-02 16:53:25 +000045 mf(mf), lis(lis), ls(ls), vrm(vrm)
Lang Hamese2b201b2009-05-18 19:03:16 +000046 {
47 mfi = mf->getFrameInfo();
48 mri = &mf->getRegInfo();
49 tii = mf->getTarget().getInstrInfo();
50 }
51
Lang Hames857c4e02009-06-17 21:01:20 +000052 /// Ensures there is space before the given machine instruction, returns the
53 /// instruction's new number.
Lang Hames233a60e2009-11-03 23:52:08 +000054 SlotIndex makeSpaceBefore(MachineInstr *mi) {
Lang Hamesb3661582009-11-14 00:02:51 +000055 //if (!lis->hasGapBeforeInstr(lis->getInstructionIndex(mi))) {
Lang Hames233a60e2009-11-03 23:52:08 +000056 // FIXME: Should be updated to use rewrite-in-place methods when they're
57 // introduced. Currently broken.
58 //lis->scaleNumbering(2);
59 //ls->scaleNumbering(2);
Lang Hamesb3661582009-11-14 00:02:51 +000060 //}
Lang Hamese2b201b2009-05-18 19:03:16 +000061
Lang Hames233a60e2009-11-03 23:52:08 +000062 SlotIndex miIdx = lis->getInstructionIndex(mi);
Lang Hames857c4e02009-06-17 21:01:20 +000063
Lang Hamesb3661582009-11-14 00:02:51 +000064 //assert(lis->hasGapBeforeInstr(miIdx));
Lang Hames857c4e02009-06-17 21:01:20 +000065
66 return miIdx;
67 }
68
69 /// Ensure there is space after the given machine instruction, returns the
70 /// instruction's new number.
Lang Hames233a60e2009-11-03 23:52:08 +000071 SlotIndex makeSpaceAfter(MachineInstr *mi) {
Lang Hamesb3661582009-11-14 00:02:51 +000072 //if (!lis->hasGapAfterInstr(lis->getInstructionIndex(mi))) {
Lang Hames233a60e2009-11-03 23:52:08 +000073 // FIXME: Should be updated to use rewrite-in-place methods when they're
74 // introduced. Currently broken.
75 // lis->scaleNumbering(2);
76 // ls->scaleNumbering(2);
Lang Hamesb3661582009-11-14 00:02:51 +000077 //}
Lang Hamesf41538d2009-06-02 16:53:25 +000078
Lang Hames233a60e2009-11-03 23:52:08 +000079 SlotIndex miIdx = lis->getInstructionIndex(mi);
Lang Hamesf41538d2009-06-02 16:53:25 +000080
Lang Hamesb3661582009-11-14 00:02:51 +000081 //assert(lis->hasGapAfterInstr(miIdx));
Lang Hamesf41538d2009-06-02 16:53:25 +000082
Lang Hames857c4e02009-06-17 21:01:20 +000083 return miIdx;
84 }
85
Lang Hames857c4e02009-06-17 21:01:20 +000086 /// Insert a store of the given vreg to the given stack slot immediately
87 /// after the given instruction. Returns the base index of the inserted
88 /// instruction. The caller is responsible for adding an appropriate
89 /// LiveInterval to the LiveIntervals analysis.
Lang Hames233a60e2009-11-03 23:52:08 +000090 SlotIndex insertStoreAfter(MachineInstr *mi, unsigned ss,
Lang Hames86511252009-09-04 20:41:11 +000091 unsigned vreg,
92 const TargetRegisterClass *trc) {
Lang Hames10382fb2009-06-19 02:17:53 +000093
Lang Hames6bbc73d2009-06-24 20:46:24 +000094 MachineBasicBlock::iterator nextInstItr(next(mi));
Lang Hames857c4e02009-06-17 21:01:20 +000095
Lang Hames233a60e2009-11-03 23:52:08 +000096 SlotIndex miIdx = makeSpaceAfter(mi);
Lang Hames857c4e02009-06-17 21:01:20 +000097
98 tii->storeRegToStackSlot(*mi->getParent(), nextInstItr, vreg,
Lang Hamesf41538d2009-06-02 16:53:25 +000099 true, ss, trc);
Lang Hames6bbc73d2009-06-24 20:46:24 +0000100 MachineBasicBlock::iterator storeInstItr(next(mi));
Lang Hamesf41538d2009-06-02 16:53:25 +0000101 MachineInstr *storeInst = &*storeInstItr;
Lang Hamesf41538d2009-06-02 16:53:25 +0000102
Lang Hamesb3661582009-11-14 00:02:51 +0000103 return lis->InsertMachineInstrInMaps(storeInst);
Lang Hamesf41538d2009-06-02 16:53:25 +0000104 }
105
Lang Hames6bbc73d2009-06-24 20:46:24 +0000106 /// Insert a store of the given vreg to the given stack slot immediately
107 /// before the given instructnion. Returns the base index of the inserted
108 /// Instruction.
Lang Hames233a60e2009-11-03 23:52:08 +0000109 SlotIndex insertStoreBefore(MachineInstr *mi, unsigned ss,
Lang Hames86511252009-09-04 20:41:11 +0000110 unsigned vreg,
111 const TargetRegisterClass *trc) {
Lang Hames233a60e2009-11-03 23:52:08 +0000112 SlotIndex miIdx = makeSpaceBefore(mi);
Lang Hames6bbc73d2009-06-24 20:46:24 +0000113
114 tii->storeRegToStackSlot(*mi->getParent(), mi, vreg, true, ss, trc);
115 MachineBasicBlock::iterator storeInstItr(prior(mi));
116 MachineInstr *storeInst = &*storeInstItr;
Lang Hames10382fb2009-06-19 02:17:53 +0000117
Lang Hamesb3661582009-11-14 00:02:51 +0000118 return lis->InsertMachineInstrInMaps(storeInst);
Lang Hames6bbc73d2009-06-24 20:46:24 +0000119 }
120
121 void insertStoreAfterInstOnInterval(LiveInterval *li,
122 MachineInstr *mi, unsigned ss,
123 unsigned vreg,
124 const TargetRegisterClass *trc) {
125
Lang Hames233a60e2009-11-03 23:52:08 +0000126 SlotIndex storeInstIdx = insertStoreAfter(mi, ss, vreg, trc);
127 SlotIndex start = lis->getInstructionIndex(mi).getDefIndex(),
128 end = storeInstIdx.getUseIndex();
Lang Hames10382fb2009-06-19 02:17:53 +0000129
130 VNInfo *vni =
131 li->getNextValue(storeInstIdx, 0, true, lis->getVNInfoAllocator());
Lang Hames86511252009-09-04 20:41:11 +0000132 vni->addKill(storeInstIdx);
Bill Wendlingc75e7d22009-08-22 20:54:03 +0000133 DEBUG(errs() << " Inserting store range: [" << start
134 << ", " << end << ")\n");
Lang Hames10382fb2009-06-19 02:17:53 +0000135 LiveRange lr(start, end, vni);
136
137 li->addRange(lr);
138 }
139
Lang Hames6bbc73d2009-06-24 20:46:24 +0000140 /// Insert a load of the given vreg from the given stack slot immediately
141 /// after the given instruction. Returns the base index of the inserted
142 /// instruction. The caller is responsibel for adding/removing an appropriate
143 /// range vreg's LiveInterval.
Lang Hames233a60e2009-11-03 23:52:08 +0000144 SlotIndex insertLoadAfter(MachineInstr *mi, unsigned ss,
Lang Hames86511252009-09-04 20:41:11 +0000145 unsigned vreg,
146 const TargetRegisterClass *trc) {
Lang Hames6bbc73d2009-06-24 20:46:24 +0000147
148 MachineBasicBlock::iterator nextInstItr(next(mi));
149
Lang Hames233a60e2009-11-03 23:52:08 +0000150 SlotIndex miIdx = makeSpaceAfter(mi);
Lang Hames6bbc73d2009-06-24 20:46:24 +0000151
152 tii->loadRegFromStackSlot(*mi->getParent(), nextInstItr, vreg, ss, trc);
153 MachineBasicBlock::iterator loadInstItr(next(mi));
154 MachineInstr *loadInst = &*loadInstItr;
Lang Hames6bbc73d2009-06-24 20:46:24 +0000155
Lang Hamesb3661582009-11-14 00:02:51 +0000156 return lis->InsertMachineInstrInMaps(loadInst);
Lang Hames6bbc73d2009-06-24 20:46:24 +0000157 }
158
159 /// Insert a load of the given vreg from the given stack slot immediately
Lang Hamesf41538d2009-06-02 16:53:25 +0000160 /// before the given instruction. Returns the base index of the inserted
161 /// instruction. The caller is responsible for adding an appropriate
162 /// LiveInterval to the LiveIntervals analysis.
Lang Hames233a60e2009-11-03 23:52:08 +0000163 SlotIndex insertLoadBefore(MachineInstr *mi, unsigned ss,
Lang Hames86511252009-09-04 20:41:11 +0000164 unsigned vreg,
165 const TargetRegisterClass *trc) {
Lang Hames233a60e2009-11-03 23:52:08 +0000166 SlotIndex miIdx = makeSpaceBefore(mi);
Lang Hames857c4e02009-06-17 21:01:20 +0000167
Lang Hames6bbc73d2009-06-24 20:46:24 +0000168 tii->loadRegFromStackSlot(*mi->getParent(), mi, vreg, ss, trc);
169 MachineBasicBlock::iterator loadInstItr(prior(mi));
Lang Hamesf41538d2009-06-02 16:53:25 +0000170 MachineInstr *loadInst = &*loadInstItr;
Lang Hamesf41538d2009-06-02 16:53:25 +0000171
Lang Hamesb3661582009-11-14 00:02:51 +0000172 return lis->InsertMachineInstrInMaps(loadInst);
Lang Hamesf41538d2009-06-02 16:53:25 +0000173 }
174
Lang Hames6bbc73d2009-06-24 20:46:24 +0000175 void insertLoadBeforeInstOnInterval(LiveInterval *li,
176 MachineInstr *mi, unsigned ss,
177 unsigned vreg,
178 const TargetRegisterClass *trc) {
Lang Hames10382fb2009-06-19 02:17:53 +0000179
Lang Hames233a60e2009-11-03 23:52:08 +0000180 SlotIndex loadInstIdx = insertLoadBefore(mi, ss, vreg, trc);
181 SlotIndex start = loadInstIdx.getDefIndex(),
182 end = lis->getInstructionIndex(mi).getUseIndex();
Lang Hames10382fb2009-06-19 02:17:53 +0000183
184 VNInfo *vni =
185 li->getNextValue(loadInstIdx, 0, true, lis->getVNInfoAllocator());
Lang Hames86511252009-09-04 20:41:11 +0000186 vni->addKill(lis->getInstructionIndex(mi));
Bill Wendlingc75e7d22009-08-22 20:54:03 +0000187 DEBUG(errs() << " Intserting load range: [" << start
188 << ", " << end << ")\n");
Lang Hames10382fb2009-06-19 02:17:53 +0000189 LiveRange lr(start, end, vni);
190
191 li->addRange(lr);
192 }
193
194
195
Lang Hamesf41538d2009-06-02 16:53:25 +0000196 /// Add spill ranges for every use/def of the live interval, inserting loads
197 /// immediately before each use, and stores after each def. No folding is
198 /// attempted.
199 std::vector<LiveInterval*> trivialSpillEverywhere(LiveInterval *li) {
Bill Wendlingc75e7d22009-08-22 20:54:03 +0000200 DEBUG(errs() << "Spilling everywhere " << *li << "\n");
Lang Hamese2b201b2009-05-18 19:03:16 +0000201
202 assert(li->weight != HUGE_VALF &&
203 "Attempting to spill already spilled value.");
204
205 assert(!li->isStackSlot() &&
206 "Trying to spill a stack slot.");
207
Bill Wendlingc75e7d22009-08-22 20:54:03 +0000208 DEBUG(errs() << "Trivial spill everywhere of reg" << li->reg << "\n");
Lang Hames6bbc73d2009-06-24 20:46:24 +0000209
Lang Hamese2b201b2009-05-18 19:03:16 +0000210 std::vector<LiveInterval*> added;
211
212 const TargetRegisterClass *trc = mri->getRegClass(li->reg);
Lang Hamese2b201b2009-05-18 19:03:16 +0000213 unsigned ss = vrm->assignVirt2StackSlot(li->reg);
214
Lang Hamesf41538d2009-06-02 16:53:25 +0000215 for (MachineRegisterInfo::reg_iterator
216 regItr = mri->reg_begin(li->reg); regItr != mri->reg_end();) {
Lang Hamese2b201b2009-05-18 19:03:16 +0000217
218 MachineInstr *mi = &*regItr;
Lang Hames6bbc73d2009-06-24 20:46:24 +0000219
Bill Wendlingc75e7d22009-08-22 20:54:03 +0000220 DEBUG(errs() << " Processing " << *mi);
Lang Hames6bbc73d2009-06-24 20:46:24 +0000221
Lang Hamesf41538d2009-06-02 16:53:25 +0000222 do {
223 ++regItr;
224 } while (regItr != mri->reg_end() && (&*regItr == mi));
225
Lang Hamese2b201b2009-05-18 19:03:16 +0000226 SmallVector<unsigned, 2> indices;
227 bool hasUse = false;
228 bool hasDef = false;
229
230 for (unsigned i = 0; i != mi->getNumOperands(); ++i) {
231 MachineOperand &op = mi->getOperand(i);
232
233 if (!op.isReg() || op.getReg() != li->reg)
234 continue;
235
236 hasUse |= mi->getOperand(i).isUse();
237 hasDef |= mi->getOperand(i).isDef();
238
239 indices.push_back(i);
240 }
241
242 unsigned newVReg = mri->createVirtualRegister(trc);
Lang Hamese2b201b2009-05-18 19:03:16 +0000243 vrm->grow();
244 vrm->assignVirt2StackSlot(newVReg, ss);
245
Lang Hamesf41538d2009-06-02 16:53:25 +0000246 LiveInterval *newLI = &lis->getOrCreateInterval(newVReg);
247 newLI->weight = HUGE_VALF;
248
Lang Hamese2b201b2009-05-18 19:03:16 +0000249 for (unsigned i = 0; i < indices.size(); ++i) {
250 mi->getOperand(indices[i]).setReg(newVReg);
251
252 if (mi->getOperand(indices[i]).isUse()) {
253 mi->getOperand(indices[i]).setIsKill(true);
254 }
255 }
256
Lang Hamesf41538d2009-06-02 16:53:25 +0000257 assert(hasUse || hasDef);
258
Lang Hamese2b201b2009-05-18 19:03:16 +0000259 if (hasUse) {
Lang Hames6bbc73d2009-06-24 20:46:24 +0000260 insertLoadBeforeInstOnInterval(newLI, mi, ss, newVReg, trc);
Lang Hamese2b201b2009-05-18 19:03:16 +0000261 }
262
263 if (hasDef) {
Lang Hames6bbc73d2009-06-24 20:46:24 +0000264 insertStoreAfterInstOnInterval(newLI, mi, ss, newVReg, trc);
Lang Hamese2b201b2009-05-18 19:03:16 +0000265 }
266
Lang Hamesf41538d2009-06-02 16:53:25 +0000267 added.push_back(newLI);
Lang Hamese2b201b2009-05-18 19:03:16 +0000268 }
269
Lang Hamese2b201b2009-05-18 19:03:16 +0000270 return added;
271 }
272
Lang Hamesf41538d2009-06-02 16:53:25 +0000273};
Lang Hamese2b201b2009-05-18 19:03:16 +0000274
275
Lang Hamesf41538d2009-06-02 16:53:25 +0000276/// Spills any live range using the spill-everywhere method with no attempt at
277/// folding.
278class TrivialSpiller : public SpillerBase {
279public:
Lang Hames10382fb2009-06-19 02:17:53 +0000280
281 TrivialSpiller(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls,
282 VirtRegMap *vrm) :
Lang Hamesf41538d2009-06-02 16:53:25 +0000283 SpillerBase(mf, lis, ls, vrm) {}
Lang Hamese2b201b2009-05-18 19:03:16 +0000284
Lang Hamesf41538d2009-06-02 16:53:25 +0000285 std::vector<LiveInterval*> spill(LiveInterval *li) {
286 return trivialSpillEverywhere(li);
Lang Hamese2b201b2009-05-18 19:03:16 +0000287 }
288
Lang Hames10382fb2009-06-19 02:17:53 +0000289 std::vector<LiveInterval*> intraBlockSplit(LiveInterval *li, VNInfo *valno) {
290 std::vector<LiveInterval*> spillIntervals;
Lang Hames6bbc73d2009-06-24 20:46:24 +0000291
292 if (!valno->isDefAccurate() && !valno->isPHIDef()) {
293 // Early out for values which have no well defined def point.
294 return spillIntervals;
295 }
296
297 // Ok.. we should be able to proceed...
298 const TargetRegisterClass *trc = mri->getRegClass(li->reg);
299 unsigned ss = vrm->assignVirt2StackSlot(li->reg);
300 vrm->grow();
301 vrm->assignVirt2StackSlot(li->reg, ss);
302
303 MachineInstr *mi = 0;
Lang Hames233a60e2009-11-03 23:52:08 +0000304 SlotIndex storeIdx = SlotIndex();
Lang Hames10382fb2009-06-19 02:17:53 +0000305
306 if (valno->isDefAccurate()) {
307 // If we have an accurate def we can just grab an iterator to the instr
308 // after the def.
Lang Hames6bbc73d2009-06-24 20:46:24 +0000309 mi = lis->getInstructionFromIndex(valno->def);
Lang Hames233a60e2009-11-03 23:52:08 +0000310 storeIdx = insertStoreAfter(mi, ss, li->reg, trc).getDefIndex();
Lang Hames10382fb2009-06-19 02:17:53 +0000311 } else {
Lang Hames6bbc73d2009-06-24 20:46:24 +0000312 // if we get here we have a PHI def.
313 mi = &lis->getMBBFromIndex(valno->def)->front();
Lang Hames233a60e2009-11-03 23:52:08 +0000314 storeIdx = insertStoreBefore(mi, ss, li->reg, trc).getDefIndex();
Lang Hames10382fb2009-06-19 02:17:53 +0000315 }
316
Lang Hames6bbc73d2009-06-24 20:46:24 +0000317 MachineBasicBlock *defBlock = mi->getParent();
Lang Hames233a60e2009-11-03 23:52:08 +0000318 SlotIndex loadIdx = SlotIndex();
Lang Hames6bbc73d2009-06-24 20:46:24 +0000319
320 // Now we need to find the load...
321 MachineBasicBlock::iterator useItr(mi);
322 for (; !useItr->readsRegister(li->reg); ++useItr) {}
323
324 if (useItr != defBlock->end()) {
325 MachineInstr *loadInst = useItr;
Lang Hames233a60e2009-11-03 23:52:08 +0000326 loadIdx = insertLoadBefore(loadInst, ss, li->reg, trc).getUseIndex();
Lang Hames6bbc73d2009-06-24 20:46:24 +0000327 }
328 else {
329 MachineInstr *loadInst = &defBlock->back();
Lang Hames233a60e2009-11-03 23:52:08 +0000330 loadIdx = insertLoadAfter(loadInst, ss, li->reg, trc).getUseIndex();
Lang Hames6bbc73d2009-06-24 20:46:24 +0000331 }
332
333 li->removeRange(storeIdx, loadIdx, true);
Lang Hames10382fb2009-06-19 02:17:53 +0000334
335 return spillIntervals;
336 }
337
Lang Hamese2b201b2009-05-18 19:03:16 +0000338};
339
340}
341
Lang Hamese2b201b2009-05-18 19:03:16 +0000342llvm::Spiller* llvm::createSpiller(MachineFunction *mf, LiveIntervals *lis,
Lang Hamesf41538d2009-06-02 16:53:25 +0000343 LiveStacks *ls, VirtRegMap *vrm) {
344 return new TrivialSpiller(mf, lis, ls, vrm);
Lang Hamese2b201b2009-05-18 19:03:16 +0000345}