Spiller.cpp revision 835ca07991c1b8ec47240b15417e1b2732480094
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/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/CommandLine.h" 22#include "llvm/Support/Debug.h" 23#include "llvm/Support/raw_ostream.h" 24 25using namespace llvm; 26 27namespace { 28 enum SpillerName { trivial, standard }; 29} 30 31static cl::opt<SpillerName> 32spillerOpt("spiller", 33 cl::desc("Spiller to use: (default: standard)"), 34 cl::Prefix, 35 cl::values(clEnumVal(trivial, "trivial spiller"), 36 clEnumVal(standard, "default spiller"), 37 clEnumValEnd), 38 cl::init(standard)); 39 40Spiller::~Spiller() {} 41 42namespace { 43 44/// Utility class for spillers. 45class SpillerBase : public Spiller { 46protected: 47 48 MachineFunction *mf; 49 LiveIntervals *lis; 50 LiveStacks *ls; 51 MachineFrameInfo *mfi; 52 MachineRegisterInfo *mri; 53 const TargetInstrInfo *tii; 54 VirtRegMap *vrm; 55 56 /// Construct a spiller base. 57 SpillerBase(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls, 58 VirtRegMap *vrm) : 59 mf(mf), lis(lis), ls(ls), vrm(vrm) 60 { 61 mfi = mf->getFrameInfo(); 62 mri = &mf->getRegInfo(); 63 tii = mf->getTarget().getInstrInfo(); 64 } 65 66 /// Add spill ranges for every use/def of the live interval, inserting loads 67 /// immediately before each use, and stores after each def. No folding or 68 /// remat is attempted. 69 std::vector<LiveInterval*> trivialSpillEverywhere(LiveInterval *li) { 70 DEBUG(errs() << "Spilling everywhere " << *li << "\n"); 71 72 assert(li->weight != HUGE_VALF && 73 "Attempting to spill already spilled value."); 74 75 assert(!li->isStackSlot() && 76 "Trying to spill a stack slot."); 77 78 DEBUG(errs() << "Trivial spill everywhere of reg" << li->reg << "\n"); 79 80 std::vector<LiveInterval*> added; 81 82 const TargetRegisterClass *trc = mri->getRegClass(li->reg); 83 unsigned ss = vrm->assignVirt2StackSlot(li->reg); 84 85 // Iterate over reg uses/defs. 86 for (MachineRegisterInfo::reg_iterator 87 regItr = mri->reg_begin(li->reg); regItr != mri->reg_end();) { 88 89 // Grab the use/def instr. 90 MachineInstr *mi = &*regItr; 91 92 DEBUG(errs() << " Processing " << *mi); 93 94 // Step regItr to the next use/def instr. 95 do { 96 ++regItr; 97 } while (regItr != mri->reg_end() && (&*regItr == mi)); 98 99 // Collect uses & defs for this instr. 100 SmallVector<unsigned, 2> indices; 101 bool hasUse = false; 102 bool hasDef = false; 103 for (unsigned i = 0; i != mi->getNumOperands(); ++i) { 104 MachineOperand &op = mi->getOperand(i); 105 if (!op.isReg() || op.getReg() != li->reg) 106 continue; 107 hasUse |= mi->getOperand(i).isUse(); 108 hasDef |= mi->getOperand(i).isDef(); 109 indices.push_back(i); 110 } 111 112 // Create a new vreg & interval for this instr. 113 unsigned newVReg = mri->createVirtualRegister(trc); 114 vrm->grow(); 115 vrm->assignVirt2StackSlot(newVReg, ss); 116 LiveInterval *newLI = &lis->getOrCreateInterval(newVReg); 117 newLI->weight = HUGE_VALF; 118 119 // Update the reg operands & kill flags. 120 for (unsigned i = 0; i < indices.size(); ++i) { 121 unsigned mopIdx = indices[i]; 122 MachineOperand &mop = mi->getOperand(mopIdx); 123 mop.setReg(newVReg); 124 if (mop.isUse() && !mi->isRegTiedToDefOperand(mopIdx)) { 125 mop.setIsKill(true); 126 } 127 } 128 assert(hasUse || hasDef); 129 130 // Insert reload if necessary. 131 MachineBasicBlock::iterator miItr(mi); 132 if (hasUse) { 133 tii->loadRegFromStackSlot(*mi->getParent(), miItr, newVReg, ss, trc); 134 MachineInstr *loadInstr(prior(miItr)); 135 SlotIndex loadIndex = 136 lis->InsertMachineInstrInMaps(loadInstr).getDefIndex(); 137 SlotIndex endIndex = loadIndex.getNextIndex(); 138 VNInfo *loadVNI = 139 newLI->getNextValue(loadIndex, 0, true, lis->getVNInfoAllocator()); 140 loadVNI->addKill(endIndex); 141 newLI->addRange(LiveRange(loadIndex, endIndex, loadVNI)); 142 } 143 144 // Insert store if necessary. 145 if (hasDef) { 146 tii->storeRegToStackSlot(*mi->getParent(), next(miItr), newVReg, true, 147 ss, trc); 148 MachineInstr *storeInstr(next(miItr)); 149 SlotIndex storeIndex = 150 lis->InsertMachineInstrInMaps(storeInstr).getDefIndex(); 151 SlotIndex beginIndex = storeIndex.getPrevIndex(); 152 VNInfo *storeVNI = 153 newLI->getNextValue(beginIndex, 0, true, lis->getVNInfoAllocator()); 154 storeVNI->addKill(storeIndex); 155 newLI->addRange(LiveRange(beginIndex, storeIndex, storeVNI)); 156 } 157 158 added.push_back(newLI); 159 } 160 161 return added; 162 } 163 164}; 165 166 167/// Spills any live range using the spill-everywhere method with no attempt at 168/// folding. 169class TrivialSpiller : public SpillerBase { 170public: 171 172 TrivialSpiller(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls, 173 VirtRegMap *vrm) 174 : SpillerBase(mf, lis, ls, vrm) {} 175 176 std::vector<LiveInterval*> spill(LiveInterval *li, 177 SmallVectorImpl<LiveInterval*> &spillIs) { 178 // Ignore spillIs - we don't use it. 179 return trivialSpillEverywhere(li); 180 } 181 182}; 183 184/// Falls back on LiveIntervals::addIntervalsForSpills. 185class StandardSpiller : public Spiller { 186private: 187 LiveIntervals *lis; 188 const MachineLoopInfo *loopInfo; 189 VirtRegMap *vrm; 190public: 191 StandardSpiller(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls, 192 const MachineLoopInfo *loopInfo, VirtRegMap *vrm) 193 : lis(lis), loopInfo(loopInfo), vrm(vrm) {} 194 195 /// Falls back on LiveIntervals::addIntervalsForSpills. 196 std::vector<LiveInterval*> spill(LiveInterval *li, 197 SmallVectorImpl<LiveInterval*> &spillIs) { 198 return lis->addIntervalsForSpills(*li, spillIs, loopInfo, *vrm); 199 } 200 201}; 202 203} 204 205llvm::Spiller* llvm::createSpiller(MachineFunction *mf, LiveIntervals *lis, 206 LiveStacks *ls, 207 const MachineLoopInfo *loopInfo, 208 VirtRegMap *vrm) { 209 switch (spillerOpt) { 210 case trivial: return new TrivialSpiller(mf, lis, ls, vrm); break; 211 case standard: return new StandardSpiller(mf, lis, ls, loopInfo, vrm); break; 212 default: llvm_unreachable("Unreachable!"); break; 213 } 214} 215