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/MachineFunction.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/Target/TargetMachine.h"
20 #include "llvm/Target/TargetInstrInfo.h"
21 #include "llvm/Support/Debug.h"
25 Spiller::~Spiller() {}
29 /// Utility class for spillers.
30 class SpillerBase
: public Spiller
{
36 MachineFrameInfo
*mfi
;
37 MachineRegisterInfo
*mri
;
38 const TargetInstrInfo
*tii
;
41 /// Construct a spiller base.
42 SpillerBase(MachineFunction
*mf
, LiveIntervals
*lis
, LiveStacks
*ls
,
44 mf(mf
), lis(lis
), ls(ls
), vrm(vrm
)
46 mfi
= mf
->getFrameInfo();
47 mri
= &mf
->getRegInfo();
48 tii
= mf
->getTarget().getInstrInfo();
51 /// Ensures there is space before the given machine instruction, returns the
52 /// instruction's new number.
53 unsigned makeSpaceBefore(MachineInstr
*mi
) {
54 if (!lis
->hasGapBeforeInstr(lis
->getInstructionIndex(mi
))) {
55 lis
->scaleNumbering(2);
56 ls
->scaleNumbering(2);
59 unsigned miIdx
= lis
->getInstructionIndex(mi
);
61 assert(lis
->hasGapBeforeInstr(miIdx
));
66 /// Ensure there is space after the given machine instruction, returns the
67 /// instruction's new number.
68 unsigned makeSpaceAfter(MachineInstr
*mi
) {
69 if (!lis
->hasGapAfterInstr(lis
->getInstructionIndex(mi
))) {
70 lis
->scaleNumbering(2);
71 ls
->scaleNumbering(2);
74 unsigned miIdx
= lis
->getInstructionIndex(mi
);
76 assert(lis
->hasGapAfterInstr(miIdx
));
81 /// Insert a store of the given vreg to the given stack slot immediately
82 /// after the given instruction. Returns the base index of the inserted
83 /// instruction. The caller is responsible for adding an appropriate
84 /// LiveInterval to the LiveIntervals analysis.
85 unsigned insertStoreAfter(MachineInstr
*mi
, unsigned ss
,
87 const TargetRegisterClass
*trc
) {
89 MachineBasicBlock::iterator
nextInstItr(next(mi
));
91 unsigned miIdx
= makeSpaceAfter(mi
);
93 tii
->storeRegToStackSlot(*mi
->getParent(), nextInstItr
, vreg
,
95 MachineBasicBlock::iterator
storeInstItr(next(mi
));
96 MachineInstr
*storeInst
= &*storeInstItr
;
97 unsigned storeInstIdx
= miIdx
+ LiveInterval::InstrSlots::NUM
;
99 assert(lis
->getInstructionFromIndex(storeInstIdx
) == 0 &&
100 "Store inst index already in use.");
102 lis
->InsertMachineInstrInMaps(storeInst
, storeInstIdx
);
107 /// Insert a store of the given vreg to the given stack slot immediately
108 /// before the given instructnion. Returns the base index of the inserted
110 unsigned insertStoreBefore(MachineInstr
*mi
, unsigned ss
,
112 const TargetRegisterClass
*trc
) {
113 unsigned miIdx
= makeSpaceBefore(mi
);
115 tii
->storeRegToStackSlot(*mi
->getParent(), mi
, vreg
, true, ss
, trc
);
116 MachineBasicBlock::iterator
storeInstItr(prior(mi
));
117 MachineInstr
*storeInst
= &*storeInstItr
;
118 unsigned storeInstIdx
= miIdx
- LiveInterval::InstrSlots::NUM
;
120 assert(lis
->getInstructionFromIndex(storeInstIdx
) == 0 &&
121 "Store inst index already in use.");
123 lis
->InsertMachineInstrInMaps(storeInst
, storeInstIdx
);
128 void insertStoreAfterInstOnInterval(LiveInterval
*li
,
129 MachineInstr
*mi
, unsigned ss
,
131 const TargetRegisterClass
*trc
) {
133 unsigned storeInstIdx
= insertStoreAfter(mi
, ss
, vreg
, trc
);
134 unsigned start
= lis
->getDefIndex(lis
->getInstructionIndex(mi
)),
135 end
= lis
->getUseIndex(storeInstIdx
);
138 li
->getNextValue(storeInstIdx
, 0, true, lis
->getVNInfoAllocator());
139 li
->addKill(vni
, storeInstIdx
, false);
140 DOUT
<< " Inserting store range: [" << start
<< ", " << end
<< ")\n";
141 LiveRange
lr(start
, end
, vni
);
146 /// Insert a load of the given vreg from the given stack slot immediately
147 /// after the given instruction. Returns the base index of the inserted
148 /// instruction. The caller is responsibel for adding/removing an appropriate
149 /// range vreg's LiveInterval.
150 unsigned insertLoadAfter(MachineInstr
*mi
, unsigned ss
,
152 const TargetRegisterClass
*trc
) {
154 MachineBasicBlock::iterator
nextInstItr(next(mi
));
156 unsigned miIdx
= makeSpaceAfter(mi
);
158 tii
->loadRegFromStackSlot(*mi
->getParent(), nextInstItr
, vreg
, ss
, trc
);
159 MachineBasicBlock::iterator
loadInstItr(next(mi
));
160 MachineInstr
*loadInst
= &*loadInstItr
;
161 unsigned loadInstIdx
= miIdx
+ LiveInterval::InstrSlots::NUM
;
163 assert(lis
->getInstructionFromIndex(loadInstIdx
) == 0 &&
164 "Store inst index already in use.");
166 lis
->InsertMachineInstrInMaps(loadInst
, loadInstIdx
);
171 /// Insert a load of the given vreg from the given stack slot immediately
172 /// before the given instruction. Returns the base index of the inserted
173 /// instruction. The caller is responsible for adding an appropriate
174 /// LiveInterval to the LiveIntervals analysis.
175 unsigned insertLoadBefore(MachineInstr
*mi
, unsigned ss
,
177 const TargetRegisterClass
*trc
) {
178 unsigned miIdx
= makeSpaceBefore(mi
);
180 tii
->loadRegFromStackSlot(*mi
->getParent(), mi
, vreg
, ss
, trc
);
181 MachineBasicBlock::iterator
loadInstItr(prior(mi
));
182 MachineInstr
*loadInst
= &*loadInstItr
;
183 unsigned loadInstIdx
= miIdx
- LiveInterval::InstrSlots::NUM
;
185 assert(lis
->getInstructionFromIndex(loadInstIdx
) == 0 &&
186 "Load inst index already in use.");
188 lis
->InsertMachineInstrInMaps(loadInst
, loadInstIdx
);
193 void insertLoadBeforeInstOnInterval(LiveInterval
*li
,
194 MachineInstr
*mi
, unsigned ss
,
196 const TargetRegisterClass
*trc
) {
198 unsigned loadInstIdx
= insertLoadBefore(mi
, ss
, vreg
, trc
);
199 unsigned start
= lis
->getDefIndex(loadInstIdx
),
200 end
= lis
->getUseIndex(lis
->getInstructionIndex(mi
));
203 li
->getNextValue(loadInstIdx
, 0, true, lis
->getVNInfoAllocator());
204 li
->addKill(vni
, lis
->getInstructionIndex(mi
), false);
205 DOUT
<< " Intserting load range: [" << start
<< ", " << end
<< ")\n";
206 LiveRange
lr(start
, end
, vni
);
213 /// Add spill ranges for every use/def of the live interval, inserting loads
214 /// immediately before each use, and stores after each def. No folding is
216 std::vector
<LiveInterval
*> trivialSpillEverywhere(LiveInterval
*li
) {
217 DOUT
<< "Spilling everywhere " << *li
<< "\n";
219 assert(li
->weight
!= HUGE_VALF
&&
220 "Attempting to spill already spilled value.");
222 assert(!li
->isStackSlot() &&
223 "Trying to spill a stack slot.");
225 DOUT
<< "Trivial spill everywhere of reg" << li
->reg
<< "\n";
227 std::vector
<LiveInterval
*> added
;
229 const TargetRegisterClass
*trc
= mri
->getRegClass(li
->reg
);
230 unsigned ss
= vrm
->assignVirt2StackSlot(li
->reg
);
232 for (MachineRegisterInfo::reg_iterator
233 regItr
= mri
->reg_begin(li
->reg
); regItr
!= mri
->reg_end();) {
235 MachineInstr
*mi
= &*regItr
;
237 DOUT
<< " Processing " << *mi
;
241 } while (regItr
!= mri
->reg_end() && (&*regItr
== mi
));
243 SmallVector
<unsigned, 2> indices
;
247 for (unsigned i
= 0; i
!= mi
->getNumOperands(); ++i
) {
248 MachineOperand
&op
= mi
->getOperand(i
);
250 if (!op
.isReg() || op
.getReg() != li
->reg
)
253 hasUse
|= mi
->getOperand(i
).isUse();
254 hasDef
|= mi
->getOperand(i
).isDef();
256 indices
.push_back(i
);
259 unsigned newVReg
= mri
->createVirtualRegister(trc
);
261 vrm
->assignVirt2StackSlot(newVReg
, ss
);
263 LiveInterval
*newLI
= &lis
->getOrCreateInterval(newVReg
);
264 newLI
->weight
= HUGE_VALF
;
266 for (unsigned i
= 0; i
< indices
.size(); ++i
) {
267 mi
->getOperand(indices
[i
]).setReg(newVReg
);
269 if (mi
->getOperand(indices
[i
]).isUse()) {
270 mi
->getOperand(indices
[i
]).setIsKill(true);
274 assert(hasUse
|| hasDef
);
277 insertLoadBeforeInstOnInterval(newLI
, mi
, ss
, newVReg
, trc
);
281 insertStoreAfterInstOnInterval(newLI
, mi
, ss
, newVReg
, trc
);
284 added
.push_back(newLI
);
293 /// Spills any live range using the spill-everywhere method with no attempt at
295 class TrivialSpiller
: public SpillerBase
{
298 TrivialSpiller(MachineFunction
*mf
, LiveIntervals
*lis
, LiveStacks
*ls
,
300 SpillerBase(mf
, lis
, ls
, vrm
) {}
302 std::vector
<LiveInterval
*> spill(LiveInterval
*li
) {
303 return trivialSpillEverywhere(li
);
306 std::vector
<LiveInterval
*> intraBlockSplit(LiveInterval
*li
, VNInfo
*valno
) {
307 std::vector
<LiveInterval
*> spillIntervals
;
309 if (!valno
->isDefAccurate() && !valno
->isPHIDef()) {
310 // Early out for values which have no well defined def point.
311 return spillIntervals
;
314 // Ok.. we should be able to proceed...
315 const TargetRegisterClass
*trc
= mri
->getRegClass(li
->reg
);
316 unsigned ss
= vrm
->assignVirt2StackSlot(li
->reg
);
318 vrm
->assignVirt2StackSlot(li
->reg
, ss
);
320 MachineInstr
*mi
= 0;
321 unsigned storeIdx
= 0;
323 if (valno
->isDefAccurate()) {
324 // If we have an accurate def we can just grab an iterator to the instr
326 mi
= lis
->getInstructionFromIndex(valno
->def
);
327 storeIdx
= insertStoreAfter(mi
, ss
, li
->reg
, trc
) +
328 LiveInterval::InstrSlots::DEF
;
330 // if we get here we have a PHI def.
331 mi
= &lis
->getMBBFromIndex(valno
->def
)->front();
332 storeIdx
= insertStoreBefore(mi
, ss
, li
->reg
, trc
) +
333 LiveInterval::InstrSlots::DEF
;
336 MachineBasicBlock
*defBlock
= mi
->getParent();
337 unsigned loadIdx
= 0;
339 // Now we need to find the load...
340 MachineBasicBlock::iterator
useItr(mi
);
341 for (; !useItr
->readsRegister(li
->reg
); ++useItr
) {}
343 if (useItr
!= defBlock
->end()) {
344 MachineInstr
*loadInst
= useItr
;
345 loadIdx
= insertLoadBefore(loadInst
, ss
, li
->reg
, trc
) +
346 LiveInterval::InstrSlots::USE
;
349 MachineInstr
*loadInst
= &defBlock
->back();
350 loadIdx
= insertLoadAfter(loadInst
, ss
, li
->reg
, trc
) +
351 LiveInterval::InstrSlots::USE
;
354 li
->removeRange(storeIdx
, loadIdx
, true);
356 return spillIntervals
;
363 llvm::Spiller
* llvm::createSpiller(MachineFunction
*mf
, LiveIntervals
*lis
,
364 LiveStacks
*ls
, VirtRegMap
*vrm
) {
365 return new TrivialSpiller(mf
, lis
, ls
, vrm
);