Spiller.cpp revision ffd1326ff8dfc652a8026c3faebf55bbba7c32c7
1//===-- 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" 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" 22 23using namespace llvm; 24 25Spiller::~Spiller() {} 26 27namespace { 28 29/// Utility class for spillers. 30class SpillerBase : public Spiller { 31protected: 32 33 MachineFunction *mf; 34 LiveIntervals *lis; 35 LiveStacks *ls; 36 MachineFrameInfo *mfi; 37 MachineRegisterInfo *mri; 38 const TargetInstrInfo *tii; 39 VirtRegMap *vrm; 40 41 /// Construct a spiller base. 42 SpillerBase(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls, 43 VirtRegMap *vrm) : 44 mf(mf), lis(lis), ls(ls), vrm(vrm) 45 { 46 mfi = mf->getFrameInfo(); 47 mri = &mf->getRegInfo(); 48 tii = mf->getTarget().getInstrInfo(); 49 } 50 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); 57 } 58 59 unsigned miIdx = lis->getInstructionIndex(mi); 60 61 assert(lis->hasGapBeforeInstr(miIdx)); 62 63 return miIdx; 64 } 65 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); 72 } 73 74 unsigned miIdx = lis->getInstructionIndex(mi); 75 76 assert(lis->hasGapAfterInstr(miIdx)); 77 78 return miIdx; 79 } 80 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, 86 unsigned vreg, 87 const TargetRegisterClass *trc) { 88 89 MachineBasicBlock::iterator nextInstItr(next(mi)); 90 91 unsigned miIdx = makeSpaceAfter(mi); 92 93 tii->storeRegToStackSlot(*mi->getParent(), nextInstItr, vreg, 94 true, ss, trc); 95 MachineBasicBlock::iterator storeInstItr(next(mi)); 96 MachineInstr *storeInst = &*storeInstItr; 97 unsigned storeInstIdx = miIdx + LiveInterval::InstrSlots::NUM; 98 99 assert(lis->getInstructionFromIndex(storeInstIdx) == 0 && 100 "Store inst index already in use."); 101 102 lis->InsertMachineInstrInMaps(storeInst, storeInstIdx); 103 104 return storeInstIdx; 105 } 106 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 109 /// Instruction. 110 unsigned insertStoreBefore(MachineInstr *mi, unsigned ss, 111 unsigned vreg, 112 const TargetRegisterClass *trc) { 113 unsigned miIdx = makeSpaceBefore(mi); 114 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; 119 120 assert(lis->getInstructionFromIndex(storeInstIdx) == 0 && 121 "Store inst index already in use."); 122 123 lis->InsertMachineInstrInMaps(storeInst, storeInstIdx); 124 125 return storeInstIdx; 126 } 127 128 void insertStoreAfterInstOnInterval(LiveInterval *li, 129 MachineInstr *mi, unsigned ss, 130 unsigned vreg, 131 const TargetRegisterClass *trc) { 132 133 unsigned storeInstIdx = insertStoreAfter(mi, ss, vreg, trc); 134 unsigned start = lis->getDefIndex(lis->getInstructionIndex(mi)), 135 end = lis->getUseIndex(storeInstIdx); 136 137 VNInfo *vni = 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); 142 143 li->addRange(lr); 144 } 145 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, 151 unsigned vreg, 152 const TargetRegisterClass *trc) { 153 154 MachineBasicBlock::iterator nextInstItr(next(mi)); 155 156 unsigned miIdx = makeSpaceAfter(mi); 157 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; 162 163 assert(lis->getInstructionFromIndex(loadInstIdx) == 0 && 164 "Store inst index already in use."); 165 166 lis->InsertMachineInstrInMaps(loadInst, loadInstIdx); 167 168 return loadInstIdx; 169 } 170 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, 176 unsigned vreg, 177 const TargetRegisterClass *trc) { 178 unsigned miIdx = makeSpaceBefore(mi); 179 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; 184 185 assert(lis->getInstructionFromIndex(loadInstIdx) == 0 && 186 "Load inst index already in use."); 187 188 lis->InsertMachineInstrInMaps(loadInst, loadInstIdx); 189 190 return loadInstIdx; 191 } 192 193 void insertLoadBeforeInstOnInterval(LiveInterval *li, 194 MachineInstr *mi, unsigned ss, 195 unsigned vreg, 196 const TargetRegisterClass *trc) { 197 198 unsigned loadInstIdx = insertLoadBefore(mi, ss, vreg, trc); 199 unsigned start = lis->getDefIndex(loadInstIdx), 200 end = lis->getUseIndex(lis->getInstructionIndex(mi)); 201 202 VNInfo *vni = 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); 207 208 li->addRange(lr); 209 } 210 211 212 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 215 /// attempted. 216 std::vector<LiveInterval*> trivialSpillEverywhere(LiveInterval *li) { 217 DOUT << "Spilling everywhere " << *li << "\n"; 218 219 assert(li->weight != HUGE_VALF && 220 "Attempting to spill already spilled value."); 221 222 assert(!li->isStackSlot() && 223 "Trying to spill a stack slot."); 224 225 DOUT << "Trivial spill everywhere of reg" << li->reg << "\n"; 226 227 std::vector<LiveInterval*> added; 228 229 const TargetRegisterClass *trc = mri->getRegClass(li->reg); 230 unsigned ss = vrm->assignVirt2StackSlot(li->reg); 231 232 for (MachineRegisterInfo::reg_iterator 233 regItr = mri->reg_begin(li->reg); regItr != mri->reg_end();) { 234 235 MachineInstr *mi = &*regItr; 236 237 DOUT << " Processing " << *mi; 238 239 do { 240 ++regItr; 241 } while (regItr != mri->reg_end() && (&*regItr == mi)); 242 243 SmallVector<unsigned, 2> indices; 244 bool hasUse = false; 245 bool hasDef = false; 246 247 for (unsigned i = 0; i != mi->getNumOperands(); ++i) { 248 MachineOperand &op = mi->getOperand(i); 249 250 if (!op.isReg() || op.getReg() != li->reg) 251 continue; 252 253 hasUse |= mi->getOperand(i).isUse(); 254 hasDef |= mi->getOperand(i).isDef(); 255 256 indices.push_back(i); 257 } 258 259 unsigned newVReg = mri->createVirtualRegister(trc); 260 vrm->grow(); 261 vrm->assignVirt2StackSlot(newVReg, ss); 262 263 LiveInterval *newLI = &lis->getOrCreateInterval(newVReg); 264 newLI->weight = HUGE_VALF; 265 266 for (unsigned i = 0; i < indices.size(); ++i) { 267 mi->getOperand(indices[i]).setReg(newVReg); 268 269 if (mi->getOperand(indices[i]).isUse()) { 270 mi->getOperand(indices[i]).setIsKill(true); 271 } 272 } 273 274 assert(hasUse || hasDef); 275 276 if (hasUse) { 277 insertLoadBeforeInstOnInterval(newLI, mi, ss, newVReg, trc); 278 } 279 280 if (hasDef) { 281 insertStoreAfterInstOnInterval(newLI, mi, ss, newVReg, trc); 282 } 283 284 added.push_back(newLI); 285 } 286 287 return added; 288 } 289 290}; 291 292 293/// Spills any live range using the spill-everywhere method with no attempt at 294/// folding. 295class TrivialSpiller : public SpillerBase { 296public: 297 298 TrivialSpiller(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls, 299 VirtRegMap *vrm) : 300 SpillerBase(mf, lis, ls, vrm) {} 301 302 std::vector<LiveInterval*> spill(LiveInterval *li) { 303 return trivialSpillEverywhere(li); 304 } 305 306 std::vector<LiveInterval*> intraBlockSplit(LiveInterval *li, VNInfo *valno) { 307 std::vector<LiveInterval*> spillIntervals; 308 309 if (!valno->isDefAccurate() && !valno->isPHIDef()) { 310 // Early out for values which have no well defined def point. 311 return spillIntervals; 312 } 313 314 // Ok.. we should be able to proceed... 315 const TargetRegisterClass *trc = mri->getRegClass(li->reg); 316 unsigned ss = vrm->assignVirt2StackSlot(li->reg); 317 vrm->grow(); 318 vrm->assignVirt2StackSlot(li->reg, ss); 319 320 MachineInstr *mi = 0; 321 unsigned storeIdx = 0; 322 323 if (valno->isDefAccurate()) { 324 // If we have an accurate def we can just grab an iterator to the instr 325 // after the def. 326 mi = lis->getInstructionFromIndex(valno->def); 327 storeIdx = insertStoreAfter(mi, ss, li->reg, trc) + 328 LiveInterval::InstrSlots::DEF; 329 } else { 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; 334 } 335 336 MachineBasicBlock *defBlock = mi->getParent(); 337 unsigned loadIdx = 0; 338 339 // Now we need to find the load... 340 MachineBasicBlock::iterator useItr(mi); 341 for (; !useItr->readsRegister(li->reg); ++useItr) {} 342 343 if (useItr != defBlock->end()) { 344 MachineInstr *loadInst = useItr; 345 loadIdx = insertLoadBefore(loadInst, ss, li->reg, trc) + 346 LiveInterval::InstrSlots::USE; 347 } 348 else { 349 MachineInstr *loadInst = &defBlock->back(); 350 loadIdx = insertLoadAfter(loadInst, ss, li->reg, trc) + 351 LiveInterval::InstrSlots::USE; 352 } 353 354 li->removeRange(storeIdx, loadIdx, true); 355 356 return spillIntervals; 357 } 358 359}; 360 361} 362 363llvm::Spiller* llvm::createSpiller(MachineFunction *mf, LiveIntervals *lis, 364 LiveStacks *ls, VirtRegMap *vrm) { 365 return new TrivialSpiller(mf, lis, ls, vrm); 366} 367