X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSpiller.cpp;h=d5b3a4a940074cfbd4840885aa1b6fb6cfe64b5a;hb=16413fa2f92803444b27b7d7fd158d449732601b;hp=74662155654e64c450eccc858f814e412d9ace5c;hpb=7896c9f436a4eda5ec15e882a7505ba482a2fcd0;p=oota-llvm.git diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp index 74662155654..d5b3a4a9400 100644 --- a/lib/CodeGen/Spiller.cpp +++ b/lib/CodeGen/Spiller.cpp @@ -10,32 +10,38 @@ #define DEBUG_TYPE "spiller" #include "Spiller.h" -#include "VirtRegMap.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/LiveRangeEdit.h" +#include "llvm/CodeGen/LiveStackAnalysis.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/CodeGen/VirtRegMap.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" using namespace llvm; namespace { - enum SpillerName { trivial, standard }; + enum SpillerName { trivial, inline_ }; } static cl::opt spillerOpt("spiller", cl::desc("Spiller to use: (default: standard)"), cl::Prefix, - cl::values(clEnumVal(trivial, "trivial spiller"), - clEnumVal(standard, "default spiller"), + cl::values(clEnumVal(trivial, "trivial spiller"), + clEnumValN(inline_, "inline", "inline spiller"), clEnumValEnd), - cl::init(standard)); + cl::init(trivial)); +// Spiller virtual destructor implementation. Spiller::~Spiller() {} namespace { @@ -43,39 +49,42 @@ namespace { /// Utility class for spillers. class SpillerBase : public Spiller { protected: - + MachineFunctionPass *pass; MachineFunction *mf; + VirtRegMap *vrm; LiveIntervals *lis; MachineFrameInfo *mfi; MachineRegisterInfo *mri; const TargetInstrInfo *tii; - VirtRegMap *vrm; - - /// Construct a spiller base. - SpillerBase(MachineFunction *mf, LiveIntervals *lis, VirtRegMap *vrm) - : mf(mf), lis(lis), vrm(vrm) + const TargetRegisterInfo *tri; + + /// Construct a spiller base. + SpillerBase(MachineFunctionPass &pass, MachineFunction &mf, VirtRegMap &vrm) + : pass(&pass), mf(&mf), vrm(&vrm) { - mfi = mf->getFrameInfo(); - mri = &mf->getRegInfo(); - tii = mf->getTarget().getInstrInfo(); + lis = &pass.getAnalysis(); + mfi = mf.getFrameInfo(); + mri = &mf.getRegInfo(); + tii = mf.getTarget().getInstrInfo(); + tri = mf.getTarget().getRegisterInfo(); } /// Add spill ranges for every use/def of the live interval, inserting loads /// immediately before each use, and stores after each def. No folding or /// remat is attempted. - std::vector trivialSpillEverywhere(LiveInterval *li) { - DEBUG(errs() << "Spilling everywhere " << *li << "\n"); + void trivialSpillEverywhere(LiveRangeEdit& LRE) { + LiveInterval* li = &LRE.getParent(); + + DEBUG(dbgs() << "Spilling everywhere " << *li << "\n"); - assert(li->weight != HUGE_VALF && + assert(li->weight != llvm::huge_valf && "Attempting to spill already spilled value."); - assert(!li->isStackSlot() && + assert(!TargetRegisterInfo::isStackSlot(li->reg) && "Trying to spill a stack slot."); - DEBUG(errs() << "Trivial spill everywhere of reg" << li->reg << "\n"); + DEBUG(dbgs() << "Trivial spill everywhere of reg" << li->reg << "\n"); - std::vector added; - const TargetRegisterClass *trc = mri->getRegClass(li->reg); unsigned ss = vrm->assignVirt2StackSlot(li->reg); @@ -86,13 +95,13 @@ protected: // Grab the use/def instr. MachineInstr *mi = &*regItr; - DEBUG(errs() << " Processing " << *mi); + DEBUG(dbgs() << " Processing " << *mi); // Step regItr to the next use/def instr. do { ++regItr; } while (regItr != mri->reg_end() && (&*regItr == mi)); - + // Collect uses & defs for this instr. SmallVector indices; bool hasUse = false; @@ -106,18 +115,14 @@ protected: indices.push_back(i); } - // Create a new vreg & interval for this instr. - unsigned newVReg = mri->createVirtualRegister(trc); - vrm->grow(); - vrm->assignVirt2StackSlot(newVReg, ss); - LiveInterval *newLI = &lis->getOrCreateInterval(newVReg); - newLI->weight = HUGE_VALF; - + // Create a new virtual register for the load and/or store. + unsigned NewVReg = LRE.create(); + // Update the reg operands & kill flags. for (unsigned i = 0; i < indices.size(); ++i) { unsigned mopIdx = indices[i]; MachineOperand &mop = mi->getOperand(mopIdx); - mop.setReg(newVReg); + mop.setReg(NewVReg); if (mop.isUse() && !mi->isRegTiedToDefOperand(mopIdx)) { mop.setIsKill(true); } @@ -127,83 +132,54 @@ protected: // Insert reload if necessary. MachineBasicBlock::iterator miItr(mi); if (hasUse) { - tii->loadRegFromStackSlot(*mi->getParent(), miItr, newVReg, ss, trc); - MachineInstr *loadInstr(prior(miItr)); - SlotIndex loadIndex = - lis->InsertMachineInstrInMaps(loadInstr).getDefIndex(); - SlotIndex endIndex = loadIndex.getNextIndex(); - VNInfo *loadVNI = - newLI->getNextValue(loadIndex, 0, true, lis->getVNInfoAllocator()); - loadVNI->addKill(endIndex); - newLI->addRange(LiveRange(loadIndex, endIndex, loadVNI)); + MachineInstrSpan MIS(miItr); + + tii->loadRegFromStackSlot(*mi->getParent(), miItr, NewVReg, ss, trc, + tri); + lis->InsertMachineInstrRangeInMaps(MIS.begin(), miItr); } // Insert store if necessary. if (hasDef) { - tii->storeRegToStackSlot(*mi->getParent(), llvm::next(miItr), newVReg, true, - ss, trc); - MachineInstr *storeInstr(llvm::next(miItr)); - SlotIndex storeIndex = - lis->InsertMachineInstrInMaps(storeInstr).getDefIndex(); - SlotIndex beginIndex = storeIndex.getPrevIndex(); - VNInfo *storeVNI = - newLI->getNextValue(beginIndex, 0, true, lis->getVNInfoAllocator()); - storeVNI->addKill(storeIndex); - newLI->addRange(LiveRange(beginIndex, storeIndex, storeVNI)); - } + MachineInstrSpan MIS(miItr); - added.push_back(newLI); + tii->storeRegToStackSlot(*mi->getParent(), llvm::next(miItr), NewVReg, + true, ss, trc, tri); + lis->InsertMachineInstrRangeInMaps(llvm::next(miItr), MIS.end()); + } } - - return added; } - }; +} // end anonymous namespace + +namespace { /// Spills any live range using the spill-everywhere method with no attempt at /// folding. class TrivialSpiller : public SpillerBase { public: - TrivialSpiller(MachineFunction *mf, LiveIntervals *lis, VirtRegMap *vrm) - : SpillerBase(mf, lis, vrm) {} + TrivialSpiller(MachineFunctionPass &pass, MachineFunction &mf, + VirtRegMap &vrm) + : SpillerBase(pass, mf, vrm) {} - std::vector spill(LiveInterval *li, - SmallVectorImpl &spillIs) { + void spill(LiveRangeEdit &LRE) { // Ignore spillIs - we don't use it. - return trivialSpillEverywhere(li); + trivialSpillEverywhere(LRE); } - }; -/// Falls back on LiveIntervals::addIntervalsForSpills. -class StandardSpiller : public Spiller { -private: - LiveIntervals *lis; - const MachineLoopInfo *loopInfo; - VirtRegMap *vrm; -public: - StandardSpiller(MachineFunction *mf, LiveIntervals *lis, - const MachineLoopInfo *loopInfo, VirtRegMap *vrm) - : lis(lis), loopInfo(loopInfo), vrm(vrm) {} - - /// Falls back on LiveIntervals::addIntervalsForSpills. - std::vector spill(LiveInterval *li, - SmallVectorImpl &spillIs) { - return lis->addIntervalsForSpills(*li, spillIs, loopInfo, *vrm); - } +} // end anonymous namespace -}; - -} +void Spiller::anchor() { } -llvm::Spiller* llvm::createSpiller(MachineFunction *mf, LiveIntervals *lis, - const MachineLoopInfo *loopInfo, - VirtRegMap *vrm) { +llvm::Spiller* llvm::createSpiller(MachineFunctionPass &pass, + MachineFunction &mf, + VirtRegMap &vrm) { switch (spillerOpt) { - case trivial: return new TrivialSpiller(mf, lis, vrm); break; - case standard: return new StandardSpiller(mf, lis, loopInfo, vrm); break; - default: llvm_unreachable("Unreachable!"); break; + case trivial: return new TrivialSpiller(pass, mf, vrm); + case inline_: return createInlineSpiller(pass, mf, vrm); } + llvm_unreachable("Invalid spiller optimization"); }