1 //===-- llvm/CodeGen/Spiller.cpp - Spiller -------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #define DEBUG_TYPE "spiller"
13 #include "VirtRegMap.h"
14 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
15 #include "llvm/CodeGen/LiveStackAnalysis.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
19 #include "llvm/Target/TargetMachine.h"
20 #include "llvm/Target/TargetInstrInfo.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/raw_ostream.h"
26 Spiller::~Spiller() {}
30 /// Utility class for spillers.
31 class SpillerBase
: public Spiller
{
37 MachineFrameInfo
*mfi
;
38 MachineRegisterInfo
*mri
;
39 const TargetInstrInfo
*tii
;
42 /// Construct a spiller base.
43 SpillerBase(MachineFunction
*mf
, LiveIntervals
*lis
, LiveStacks
*ls
,
45 mf(mf
), lis(lis
), ls(ls
), vrm(vrm
)
47 mfi
= mf
->getFrameInfo();
48 mri
= &mf
->getRegInfo();
49 tii
= mf
->getTarget().getInstrInfo();
52 /// Ensures there is space before the given machine instruction, returns the
53 /// instruction's new number.
54 MachineInstrIndex
makeSpaceBefore(MachineInstr
*mi
) {
55 if (!lis
->hasGapBeforeInstr(lis
->getInstructionIndex(mi
))) {
56 lis
->scaleNumbering(2);
57 ls
->scaleNumbering(2);
60 MachineInstrIndex miIdx
= lis
->getInstructionIndex(mi
);
62 assert(lis
->hasGapBeforeInstr(miIdx
));
67 /// Ensure there is space after the given machine instruction, returns the
68 /// instruction's new number.
69 MachineInstrIndex
makeSpaceAfter(MachineInstr
*mi
) {
70 if (!lis
->hasGapAfterInstr(lis
->getInstructionIndex(mi
))) {
71 lis
->scaleNumbering(2);
72 ls
->scaleNumbering(2);
75 MachineInstrIndex miIdx
= lis
->getInstructionIndex(mi
);
77 assert(lis
->hasGapAfterInstr(miIdx
));
82 /// Insert a store of the given vreg to the given stack slot immediately
83 /// after the given instruction. Returns the base index of the inserted
84 /// instruction. The caller is responsible for adding an appropriate
85 /// LiveInterval to the LiveIntervals analysis.
86 MachineInstrIndex
insertStoreAfter(MachineInstr
*mi
, unsigned ss
,
88 const TargetRegisterClass
*trc
) {
90 MachineBasicBlock::iterator
nextInstItr(next(mi
));
92 MachineInstrIndex miIdx
= makeSpaceAfter(mi
);
94 tii
->storeRegToStackSlot(*mi
->getParent(), nextInstItr
, vreg
,
96 MachineBasicBlock::iterator
storeInstItr(next(mi
));
97 MachineInstr
*storeInst
= &*storeInstItr
;
98 MachineInstrIndex storeInstIdx
= lis
->getNextIndex(miIdx
);
100 assert(lis
->getInstructionFromIndex(storeInstIdx
) == 0 &&
101 "Store inst index already in use.");
103 lis
->InsertMachineInstrInMaps(storeInst
, storeInstIdx
);
108 /// Insert a store of the given vreg to the given stack slot immediately
109 /// before the given instructnion. Returns the base index of the inserted
111 MachineInstrIndex
insertStoreBefore(MachineInstr
*mi
, unsigned ss
,
113 const TargetRegisterClass
*trc
) {
114 MachineInstrIndex miIdx
= makeSpaceBefore(mi
);
116 tii
->storeRegToStackSlot(*mi
->getParent(), mi
, vreg
, true, ss
, trc
);
117 MachineBasicBlock::iterator
storeInstItr(prior(mi
));
118 MachineInstr
*storeInst
= &*storeInstItr
;
119 MachineInstrIndex storeInstIdx
= lis
->getPrevIndex(miIdx
);
121 assert(lis
->getInstructionFromIndex(storeInstIdx
) == 0 &&
122 "Store inst index already in use.");
124 lis
->InsertMachineInstrInMaps(storeInst
, storeInstIdx
);
129 void insertStoreAfterInstOnInterval(LiveInterval
*li
,
130 MachineInstr
*mi
, unsigned ss
,
132 const TargetRegisterClass
*trc
) {
134 MachineInstrIndex storeInstIdx
= insertStoreAfter(mi
, ss
, vreg
, trc
);
135 MachineInstrIndex start
= lis
->getDefIndex(lis
->getInstructionIndex(mi
)),
136 end
= lis
->getUseIndex(storeInstIdx
);
139 li
->getNextValue(storeInstIdx
, 0, true, lis
->getVNInfoAllocator());
140 vni
->addKill(storeInstIdx
);
141 DEBUG(errs() << " Inserting store range: [" << start
142 << ", " << end
<< ")\n");
143 LiveRange
lr(start
, end
, vni
);
148 /// Insert a load of the given vreg from the given stack slot immediately
149 /// after the given instruction. Returns the base index of the inserted
150 /// instruction. The caller is responsibel for adding/removing an appropriate
151 /// range vreg's LiveInterval.
152 MachineInstrIndex
insertLoadAfter(MachineInstr
*mi
, unsigned ss
,
154 const TargetRegisterClass
*trc
) {
156 MachineBasicBlock::iterator
nextInstItr(next(mi
));
158 MachineInstrIndex miIdx
= makeSpaceAfter(mi
);
160 tii
->loadRegFromStackSlot(*mi
->getParent(), nextInstItr
, vreg
, ss
, trc
);
161 MachineBasicBlock::iterator
loadInstItr(next(mi
));
162 MachineInstr
*loadInst
= &*loadInstItr
;
163 MachineInstrIndex loadInstIdx
= lis
->getNextIndex(miIdx
);
165 assert(lis
->getInstructionFromIndex(loadInstIdx
) == 0 &&
166 "Store inst index already in use.");
168 lis
->InsertMachineInstrInMaps(loadInst
, loadInstIdx
);
173 /// Insert a load of the given vreg from the given stack slot immediately
174 /// before the given instruction. Returns the base index of the inserted
175 /// instruction. The caller is responsible for adding an appropriate
176 /// LiveInterval to the LiveIntervals analysis.
177 MachineInstrIndex
insertLoadBefore(MachineInstr
*mi
, unsigned ss
,
179 const TargetRegisterClass
*trc
) {
180 MachineInstrIndex miIdx
= makeSpaceBefore(mi
);
182 tii
->loadRegFromStackSlot(*mi
->getParent(), mi
, vreg
, ss
, trc
);
183 MachineBasicBlock::iterator
loadInstItr(prior(mi
));
184 MachineInstr
*loadInst
= &*loadInstItr
;
185 MachineInstrIndex loadInstIdx
= lis
->getPrevIndex(miIdx
);
187 assert(lis
->getInstructionFromIndex(loadInstIdx
) == 0 &&
188 "Load inst index already in use.");
190 lis
->InsertMachineInstrInMaps(loadInst
, loadInstIdx
);
195 void insertLoadBeforeInstOnInterval(LiveInterval
*li
,
196 MachineInstr
*mi
, unsigned ss
,
198 const TargetRegisterClass
*trc
) {
200 MachineInstrIndex loadInstIdx
= insertLoadBefore(mi
, ss
, vreg
, trc
);
201 MachineInstrIndex start
= lis
->getDefIndex(loadInstIdx
),
202 end
= lis
->getUseIndex(lis
->getInstructionIndex(mi
));
205 li
->getNextValue(loadInstIdx
, 0, true, lis
->getVNInfoAllocator());
206 vni
->addKill(lis
->getInstructionIndex(mi
));
207 DEBUG(errs() << " Intserting load range: [" << start
208 << ", " << end
<< ")\n");
209 LiveRange
lr(start
, end
, vni
);
216 /// Add spill ranges for every use/def of the live interval, inserting loads
217 /// immediately before each use, and stores after each def. No folding is
219 std::vector
<LiveInterval
*> trivialSpillEverywhere(LiveInterval
*li
) {
220 DEBUG(errs() << "Spilling everywhere " << *li
<< "\n");
222 assert(li
->weight
!= HUGE_VALF
&&
223 "Attempting to spill already spilled value.");
225 assert(!li
->isStackSlot() &&
226 "Trying to spill a stack slot.");
228 DEBUG(errs() << "Trivial spill everywhere of reg" << li
->reg
<< "\n");
230 std::vector
<LiveInterval
*> added
;
232 const TargetRegisterClass
*trc
= mri
->getRegClass(li
->reg
);
233 unsigned ss
= vrm
->assignVirt2StackSlot(li
->reg
);
235 for (MachineRegisterInfo::reg_iterator
236 regItr
= mri
->reg_begin(li
->reg
); regItr
!= mri
->reg_end();) {
238 MachineInstr
*mi
= &*regItr
;
240 DEBUG(errs() << " Processing " << *mi
);
244 } while (regItr
!= mri
->reg_end() && (&*regItr
== mi
));
246 SmallVector
<unsigned, 2> indices
;
250 for (unsigned i
= 0; i
!= mi
->getNumOperands(); ++i
) {
251 MachineOperand
&op
= mi
->getOperand(i
);
253 if (!op
.isReg() || op
.getReg() != li
->reg
)
256 hasUse
|= mi
->getOperand(i
).isUse();
257 hasDef
|= mi
->getOperand(i
).isDef();
259 indices
.push_back(i
);
262 unsigned newVReg
= mri
->createVirtualRegister(trc
);
264 vrm
->assignVirt2StackSlot(newVReg
, ss
);
266 LiveInterval
*newLI
= &lis
->getOrCreateInterval(newVReg
);
267 newLI
->weight
= HUGE_VALF
;
269 for (unsigned i
= 0; i
< indices
.size(); ++i
) {
270 mi
->getOperand(indices
[i
]).setReg(newVReg
);
272 if (mi
->getOperand(indices
[i
]).isUse()) {
273 mi
->getOperand(indices
[i
]).setIsKill(true);
277 assert(hasUse
|| hasDef
);
280 insertLoadBeforeInstOnInterval(newLI
, mi
, ss
, newVReg
, trc
);
284 insertStoreAfterInstOnInterval(newLI
, mi
, ss
, newVReg
, trc
);
287 added
.push_back(newLI
);
296 /// Spills any live range using the spill-everywhere method with no attempt at
298 class TrivialSpiller
: public SpillerBase
{
301 TrivialSpiller(MachineFunction
*mf
, LiveIntervals
*lis
, LiveStacks
*ls
,
303 SpillerBase(mf
, lis
, ls
, vrm
) {}
305 std::vector
<LiveInterval
*> spill(LiveInterval
*li
) {
306 return trivialSpillEverywhere(li
);
309 std::vector
<LiveInterval
*> intraBlockSplit(LiveInterval
*li
, VNInfo
*valno
) {
310 std::vector
<LiveInterval
*> spillIntervals
;
312 if (!valno
->isDefAccurate() && !valno
->isPHIDef()) {
313 // Early out for values which have no well defined def point.
314 return spillIntervals
;
317 // Ok.. we should be able to proceed...
318 const TargetRegisterClass
*trc
= mri
->getRegClass(li
->reg
);
319 unsigned ss
= vrm
->assignVirt2StackSlot(li
->reg
);
321 vrm
->assignVirt2StackSlot(li
->reg
, ss
);
323 MachineInstr
*mi
= 0;
324 MachineInstrIndex storeIdx
= MachineInstrIndex();
326 if (valno
->isDefAccurate()) {
327 // If we have an accurate def we can just grab an iterator to the instr
329 mi
= lis
->getInstructionFromIndex(valno
->def
);
330 storeIdx
= lis
->getDefIndex(insertStoreAfter(mi
, ss
, li
->reg
, trc
));
332 // if we get here we have a PHI def.
333 mi
= &lis
->getMBBFromIndex(valno
->def
)->front();
334 storeIdx
= lis
->getDefIndex(insertStoreBefore(mi
, ss
, li
->reg
, trc
));
337 MachineBasicBlock
*defBlock
= mi
->getParent();
338 MachineInstrIndex loadIdx
= MachineInstrIndex();
340 // Now we need to find the load...
341 MachineBasicBlock::iterator
useItr(mi
);
342 for (; !useItr
->readsRegister(li
->reg
); ++useItr
) {}
344 if (useItr
!= defBlock
->end()) {
345 MachineInstr
*loadInst
= useItr
;
346 loadIdx
= lis
->getUseIndex(insertLoadBefore(loadInst
, ss
, li
->reg
, trc
));
349 MachineInstr
*loadInst
= &defBlock
->back();
350 loadIdx
= lis
->getUseIndex(insertLoadAfter(loadInst
, ss
, li
->reg
, trc
));
353 li
->removeRange(storeIdx
, loadIdx
, true);
355 return spillIntervals
;
362 llvm::Spiller
* llvm::createSpiller(MachineFunction
*mf
, LiveIntervals
*lis
,
363 LiveStacks
*ls
, VirtRegMap
*vrm
) {
364 return new TrivialSpiller(mf
, lis
, ls
, vrm
);