blob: 95e85be5b817463695eebf9913ff1e726645c36d [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 Hames857c4e02009-06-17 21:01:20 +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 Hames857c4e02009-06-17 21:01:20 +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
64 assert(lis->hasGapBeforeInstr(miIdx));
65
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 Hamesf41538d2009-06-02 16:53:25 +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 Hamesf41538d2009-06-02 16:53:25 +000077 }
78
Lang Hames233a60e2009-11-03 23:52:08 +000079 SlotIndex miIdx = lis->getInstructionIndex(mi);
Lang Hamesf41538d2009-06-02 16:53:25 +000080
81 assert(lis->hasGapAfterInstr(miIdx));
82
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 Hames233a60e2009-11-03 23:52:08 +0000102 SlotIndex storeInstIdx = miIdx.getNextIndex();
Lang Hamesf41538d2009-06-02 16:53:25 +0000103
104 assert(lis->getInstructionFromIndex(storeInstIdx) == 0 &&
105 "Store inst index already in use.");
106
107 lis->InsertMachineInstrInMaps(storeInst, storeInstIdx);
108
109 return storeInstIdx;
110 }
111
Lang Hames6bbc73d2009-06-24 20:46:24 +0000112 /// Insert a store of the given vreg to the given stack slot immediately
113 /// before the given instructnion. Returns the base index of the inserted
114 /// Instruction.
Lang Hames233a60e2009-11-03 23:52:08 +0000115 SlotIndex insertStoreBefore(MachineInstr *mi, unsigned ss,
Lang Hames86511252009-09-04 20:41:11 +0000116 unsigned vreg,
117 const TargetRegisterClass *trc) {
Lang Hames233a60e2009-11-03 23:52:08 +0000118 SlotIndex miIdx = makeSpaceBefore(mi);
Lang Hames6bbc73d2009-06-24 20:46:24 +0000119
120 tii->storeRegToStackSlot(*mi->getParent(), mi, vreg, true, ss, trc);
121 MachineBasicBlock::iterator storeInstItr(prior(mi));
122 MachineInstr *storeInst = &*storeInstItr;
Lang Hames233a60e2009-11-03 23:52:08 +0000123 SlotIndex storeInstIdx = miIdx.getPrevIndex();
Lang Hames10382fb2009-06-19 02:17:53 +0000124
Lang Hames6bbc73d2009-06-24 20:46:24 +0000125 assert(lis->getInstructionFromIndex(storeInstIdx) == 0 &&
126 "Store inst index already in use.");
127
128 lis->InsertMachineInstrInMaps(storeInst, storeInstIdx);
129
130 return storeInstIdx;
131 }
132
133 void insertStoreAfterInstOnInterval(LiveInterval *li,
134 MachineInstr *mi, unsigned ss,
135 unsigned vreg,
136 const TargetRegisterClass *trc) {
137
Lang Hames233a60e2009-11-03 23:52:08 +0000138 SlotIndex storeInstIdx = insertStoreAfter(mi, ss, vreg, trc);
139 SlotIndex start = lis->getInstructionIndex(mi).getDefIndex(),
140 end = storeInstIdx.getUseIndex();
Lang Hames10382fb2009-06-19 02:17:53 +0000141
142 VNInfo *vni =
143 li->getNextValue(storeInstIdx, 0, true, lis->getVNInfoAllocator());
Lang Hames86511252009-09-04 20:41:11 +0000144 vni->addKill(storeInstIdx);
Bill Wendlingc75e7d22009-08-22 20:54:03 +0000145 DEBUG(errs() << " Inserting store range: [" << start
146 << ", " << end << ")\n");
Lang Hames10382fb2009-06-19 02:17:53 +0000147 LiveRange lr(start, end, vni);
148
149 li->addRange(lr);
150 }
151
Lang Hames6bbc73d2009-06-24 20:46:24 +0000152 /// Insert a load of the given vreg from the given stack slot immediately
153 /// after the given instruction. Returns the base index of the inserted
154 /// instruction. The caller is responsibel for adding/removing an appropriate
155 /// range vreg's LiveInterval.
Lang Hames233a60e2009-11-03 23:52:08 +0000156 SlotIndex insertLoadAfter(MachineInstr *mi, unsigned ss,
Lang Hames86511252009-09-04 20:41:11 +0000157 unsigned vreg,
158 const TargetRegisterClass *trc) {
Lang Hames6bbc73d2009-06-24 20:46:24 +0000159
160 MachineBasicBlock::iterator nextInstItr(next(mi));
161
Lang Hames233a60e2009-11-03 23:52:08 +0000162 SlotIndex miIdx = makeSpaceAfter(mi);
Lang Hames6bbc73d2009-06-24 20:46:24 +0000163
164 tii->loadRegFromStackSlot(*mi->getParent(), nextInstItr, vreg, ss, trc);
165 MachineBasicBlock::iterator loadInstItr(next(mi));
166 MachineInstr *loadInst = &*loadInstItr;
Lang Hames233a60e2009-11-03 23:52:08 +0000167 SlotIndex loadInstIdx = miIdx.getNextIndex();
Lang Hames6bbc73d2009-06-24 20:46:24 +0000168
169 assert(lis->getInstructionFromIndex(loadInstIdx) == 0 &&
170 "Store inst index already in use.");
171
172 lis->InsertMachineInstrInMaps(loadInst, loadInstIdx);
173
174 return loadInstIdx;
175 }
176
177 /// Insert a load of the given vreg from the given stack slot immediately
Lang Hamesf41538d2009-06-02 16:53:25 +0000178 /// before the given instruction. Returns the base index of the inserted
179 /// instruction. The caller is responsible for adding an appropriate
180 /// LiveInterval to the LiveIntervals analysis.
Lang Hames233a60e2009-11-03 23:52:08 +0000181 SlotIndex insertLoadBefore(MachineInstr *mi, unsigned ss,
Lang Hames86511252009-09-04 20:41:11 +0000182 unsigned vreg,
183 const TargetRegisterClass *trc) {
Lang Hames233a60e2009-11-03 23:52:08 +0000184 SlotIndex miIdx = makeSpaceBefore(mi);
Lang Hames857c4e02009-06-17 21:01:20 +0000185
Lang Hames6bbc73d2009-06-24 20:46:24 +0000186 tii->loadRegFromStackSlot(*mi->getParent(), mi, vreg, ss, trc);
187 MachineBasicBlock::iterator loadInstItr(prior(mi));
Lang Hamesf41538d2009-06-02 16:53:25 +0000188 MachineInstr *loadInst = &*loadInstItr;
Lang Hames233a60e2009-11-03 23:52:08 +0000189 SlotIndex loadInstIdx = miIdx.getPrevIndex();
Lang Hamesf41538d2009-06-02 16:53:25 +0000190
191 assert(lis->getInstructionFromIndex(loadInstIdx) == 0 &&
192 "Load inst index already in use.");
193
194 lis->InsertMachineInstrInMaps(loadInst, loadInstIdx);
195
196 return loadInstIdx;
197 }
198
Lang Hames6bbc73d2009-06-24 20:46:24 +0000199 void insertLoadBeforeInstOnInterval(LiveInterval *li,
200 MachineInstr *mi, unsigned ss,
201 unsigned vreg,
202 const TargetRegisterClass *trc) {
Lang Hames10382fb2009-06-19 02:17:53 +0000203
Lang Hames233a60e2009-11-03 23:52:08 +0000204 SlotIndex loadInstIdx = insertLoadBefore(mi, ss, vreg, trc);
205 SlotIndex start = loadInstIdx.getDefIndex(),
206 end = lis->getInstructionIndex(mi).getUseIndex();
Lang Hames10382fb2009-06-19 02:17:53 +0000207
208 VNInfo *vni =
209 li->getNextValue(loadInstIdx, 0, true, lis->getVNInfoAllocator());
Lang Hames86511252009-09-04 20:41:11 +0000210 vni->addKill(lis->getInstructionIndex(mi));
Bill Wendlingc75e7d22009-08-22 20:54:03 +0000211 DEBUG(errs() << " Intserting load range: [" << start
212 << ", " << end << ")\n");
Lang Hames10382fb2009-06-19 02:17:53 +0000213 LiveRange lr(start, end, vni);
214
215 li->addRange(lr);
216 }
217
218
219
Lang Hamesf41538d2009-06-02 16:53:25 +0000220 /// Add spill ranges for every use/def of the live interval, inserting loads
221 /// immediately before each use, and stores after each def. No folding is
222 /// attempted.
223 std::vector<LiveInterval*> trivialSpillEverywhere(LiveInterval *li) {
Bill Wendlingc75e7d22009-08-22 20:54:03 +0000224 DEBUG(errs() << "Spilling everywhere " << *li << "\n");
Lang Hamese2b201b2009-05-18 19:03:16 +0000225
226 assert(li->weight != HUGE_VALF &&
227 "Attempting to spill already spilled value.");
228
229 assert(!li->isStackSlot() &&
230 "Trying to spill a stack slot.");
231
Bill Wendlingc75e7d22009-08-22 20:54:03 +0000232 DEBUG(errs() << "Trivial spill everywhere of reg" << li->reg << "\n");
Lang Hames6bbc73d2009-06-24 20:46:24 +0000233
Lang Hamese2b201b2009-05-18 19:03:16 +0000234 std::vector<LiveInterval*> added;
235
236 const TargetRegisterClass *trc = mri->getRegClass(li->reg);
Lang Hamese2b201b2009-05-18 19:03:16 +0000237 unsigned ss = vrm->assignVirt2StackSlot(li->reg);
238
Lang Hamesf41538d2009-06-02 16:53:25 +0000239 for (MachineRegisterInfo::reg_iterator
240 regItr = mri->reg_begin(li->reg); regItr != mri->reg_end();) {
Lang Hamese2b201b2009-05-18 19:03:16 +0000241
242 MachineInstr *mi = &*regItr;
Lang Hames6bbc73d2009-06-24 20:46:24 +0000243
Bill Wendlingc75e7d22009-08-22 20:54:03 +0000244 DEBUG(errs() << " Processing " << *mi);
Lang Hames6bbc73d2009-06-24 20:46:24 +0000245
Lang Hamesf41538d2009-06-02 16:53:25 +0000246 do {
247 ++regItr;
248 } while (regItr != mri->reg_end() && (&*regItr == mi));
249
Lang Hamese2b201b2009-05-18 19:03:16 +0000250 SmallVector<unsigned, 2> indices;
251 bool hasUse = false;
252 bool hasDef = false;
253
254 for (unsigned i = 0; i != mi->getNumOperands(); ++i) {
255 MachineOperand &op = mi->getOperand(i);
256
257 if (!op.isReg() || op.getReg() != li->reg)
258 continue;
259
260 hasUse |= mi->getOperand(i).isUse();
261 hasDef |= mi->getOperand(i).isDef();
262
263 indices.push_back(i);
264 }
265
266 unsigned newVReg = mri->createVirtualRegister(trc);
Lang Hamese2b201b2009-05-18 19:03:16 +0000267 vrm->grow();
268 vrm->assignVirt2StackSlot(newVReg, ss);
269
Lang Hamesf41538d2009-06-02 16:53:25 +0000270 LiveInterval *newLI = &lis->getOrCreateInterval(newVReg);
271 newLI->weight = HUGE_VALF;
272
Lang Hamese2b201b2009-05-18 19:03:16 +0000273 for (unsigned i = 0; i < indices.size(); ++i) {
274 mi->getOperand(indices[i]).setReg(newVReg);
275
276 if (mi->getOperand(indices[i]).isUse()) {
277 mi->getOperand(indices[i]).setIsKill(true);
278 }
279 }
280
Lang Hamesf41538d2009-06-02 16:53:25 +0000281 assert(hasUse || hasDef);
282
Lang Hamese2b201b2009-05-18 19:03:16 +0000283 if (hasUse) {
Lang Hames6bbc73d2009-06-24 20:46:24 +0000284 insertLoadBeforeInstOnInterval(newLI, mi, ss, newVReg, trc);
Lang Hamese2b201b2009-05-18 19:03:16 +0000285 }
286
287 if (hasDef) {
Lang Hames6bbc73d2009-06-24 20:46:24 +0000288 insertStoreAfterInstOnInterval(newLI, mi, ss, newVReg, trc);
Lang Hamese2b201b2009-05-18 19:03:16 +0000289 }
290
Lang Hamesf41538d2009-06-02 16:53:25 +0000291 added.push_back(newLI);
Lang Hamese2b201b2009-05-18 19:03:16 +0000292 }
293
Lang Hamese2b201b2009-05-18 19:03:16 +0000294 return added;
295 }
296
Lang Hamesf41538d2009-06-02 16:53:25 +0000297};
Lang Hamese2b201b2009-05-18 19:03:16 +0000298
299
Lang Hamesf41538d2009-06-02 16:53:25 +0000300/// Spills any live range using the spill-everywhere method with no attempt at
301/// folding.
302class TrivialSpiller : public SpillerBase {
303public:
Lang Hames10382fb2009-06-19 02:17:53 +0000304
305 TrivialSpiller(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls,
306 VirtRegMap *vrm) :
Lang Hamesf41538d2009-06-02 16:53:25 +0000307 SpillerBase(mf, lis, ls, vrm) {}
Lang Hamese2b201b2009-05-18 19:03:16 +0000308
Lang Hamesf41538d2009-06-02 16:53:25 +0000309 std::vector<LiveInterval*> spill(LiveInterval *li) {
310 return trivialSpillEverywhere(li);
Lang Hamese2b201b2009-05-18 19:03:16 +0000311 }
312
Lang Hames10382fb2009-06-19 02:17:53 +0000313 std::vector<LiveInterval*> intraBlockSplit(LiveInterval *li, VNInfo *valno) {
314 std::vector<LiveInterval*> spillIntervals;
Lang Hames6bbc73d2009-06-24 20:46:24 +0000315
316 if (!valno->isDefAccurate() && !valno->isPHIDef()) {
317 // Early out for values which have no well defined def point.
318 return spillIntervals;
319 }
320
321 // Ok.. we should be able to proceed...
322 const TargetRegisterClass *trc = mri->getRegClass(li->reg);
323 unsigned ss = vrm->assignVirt2StackSlot(li->reg);
324 vrm->grow();
325 vrm->assignVirt2StackSlot(li->reg, ss);
326
327 MachineInstr *mi = 0;
Lang Hames233a60e2009-11-03 23:52:08 +0000328 SlotIndex storeIdx = SlotIndex();
Lang Hames10382fb2009-06-19 02:17:53 +0000329
330 if (valno->isDefAccurate()) {
331 // If we have an accurate def we can just grab an iterator to the instr
332 // after the def.
Lang Hames6bbc73d2009-06-24 20:46:24 +0000333 mi = lis->getInstructionFromIndex(valno->def);
Lang Hames233a60e2009-11-03 23:52:08 +0000334 storeIdx = insertStoreAfter(mi, ss, li->reg, trc).getDefIndex();
Lang Hames10382fb2009-06-19 02:17:53 +0000335 } else {
Lang Hames6bbc73d2009-06-24 20:46:24 +0000336 // if we get here we have a PHI def.
337 mi = &lis->getMBBFromIndex(valno->def)->front();
Lang Hames233a60e2009-11-03 23:52:08 +0000338 storeIdx = insertStoreBefore(mi, ss, li->reg, trc).getDefIndex();
Lang Hames10382fb2009-06-19 02:17:53 +0000339 }
340
Lang Hames6bbc73d2009-06-24 20:46:24 +0000341 MachineBasicBlock *defBlock = mi->getParent();
Lang Hames233a60e2009-11-03 23:52:08 +0000342 SlotIndex loadIdx = SlotIndex();
Lang Hames6bbc73d2009-06-24 20:46:24 +0000343
344 // Now we need to find the load...
345 MachineBasicBlock::iterator useItr(mi);
346 for (; !useItr->readsRegister(li->reg); ++useItr) {}
347
348 if (useItr != defBlock->end()) {
349 MachineInstr *loadInst = useItr;
Lang Hames233a60e2009-11-03 23:52:08 +0000350 loadIdx = insertLoadBefore(loadInst, ss, li->reg, trc).getUseIndex();
Lang Hames6bbc73d2009-06-24 20:46:24 +0000351 }
352 else {
353 MachineInstr *loadInst = &defBlock->back();
Lang Hames233a60e2009-11-03 23:52:08 +0000354 loadIdx = insertLoadAfter(loadInst, ss, li->reg, trc).getUseIndex();
Lang Hames6bbc73d2009-06-24 20:46:24 +0000355 }
356
357 li->removeRange(storeIdx, loadIdx, true);
Lang Hames10382fb2009-06-19 02:17:53 +0000358
359 return spillIntervals;
360 }
361
Lang Hamese2b201b2009-05-18 19:03:16 +0000362};
363
364}
365
Lang Hamese2b201b2009-05-18 19:03:16 +0000366llvm::Spiller* llvm::createSpiller(MachineFunction *mf, LiveIntervals *lis,
Lang Hamesf41538d2009-06-02 16:53:25 +0000367 LiveStacks *ls, VirtRegMap *vrm) {
368 return new TrivialSpiller(mf, lis, ls, vrm);
Lang Hamese2b201b2009-05-18 19:03:16 +0000369}