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