X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSpiller.cpp;h=59d5ab33c994f6e69c2441d3407402aa2a5ad2dc;hb=df3f25656d97deda816f74f10be14821fd5259e9;hp=b95f54bff967ea3b79c94090c6bd10421ecfd92c;hpb=d540801e13d1aef4f074f8c32115f55104130e28;p=oota-llvm.git diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp index b95f54bff96..59d5ab33c99 100644 --- a/lib/CodeGen/Spiller.cpp +++ b/lib/CodeGen/Spiller.cpp @@ -14,6 +14,8 @@ #include "llvm/CodeGen/LiveIntervalAnalysis.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" @@ -48,29 +50,31 @@ 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; const TargetRegisterInfo *tri; - VirtRegMap *vrm; - - /// Construct a spiller base. - SpillerBase(MachineFunction *mf, LiveIntervals *lis, VirtRegMap *vrm) - : mf(mf), lis(lis), vrm(vrm) + + /// 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(); - tri = mf->getTarget().getRegisterInfo(); + 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. void trivialSpillEverywhere(LiveInterval *li, - std::vector &newIntervals) { + SmallVectorImpl &newIntervals) { DEBUG(dbgs() << "Spilling everywhere " << *li << "\n"); assert(li->weight != HUGE_VALF && @@ -97,7 +101,7 @@ protected: do { ++regItr; } while (regItr != mri->reg_end() && (&*regItr == mi)); - + // Collect uses & defs for this instr. SmallVector indices; bool hasUse = false; @@ -117,7 +121,7 @@ protected: vrm->assignVirt2StackSlot(newVReg, ss); LiveInterval *newLI = &lis->getOrCreateInterval(newVReg); newLI->weight = HUGE_VALF; - + // Update the reg operands & kill flags. for (unsigned i = 0; i < indices.size(); ++i) { unsigned mopIdx = indices[i]; @@ -172,13 +176,13 @@ namespace { 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) {} void spill(LiveInterval *li, - std::vector &newIntervals, - SmallVectorImpl &, - SlotIndex*) { + SmallVectorImpl &newIntervals, + SmallVectorImpl &) { // Ignore spillIs - we don't use it. trivialSpillEverywhere(li, newIntervals); } @@ -192,18 +196,19 @@ namespace { class StandardSpiller : public Spiller { protected: LiveIntervals *lis; - const MachineLoopInfo *loopInfo; + MachineLoopInfo *loopInfo; VirtRegMap *vrm; public: - StandardSpiller(LiveIntervals *lis, const MachineLoopInfo *loopInfo, - VirtRegMap *vrm) - : lis(lis), loopInfo(loopInfo), vrm(vrm) {} + StandardSpiller(MachineFunctionPass &pass, MachineFunction &mf, + VirtRegMap &vrm) + : lis(&pass.getAnalysis()), + loopInfo(pass.getAnalysisIfAvailable()), + vrm(&vrm) {} /// Falls back on LiveIntervals::addIntervalsForSpills. void spill(LiveInterval *li, - std::vector &newIntervals, - SmallVectorImpl &spillIs, - SlotIndex*) { + SmallVectorImpl &newIntervals, + SmallVectorImpl &spillIs) { std::vector added = lis->addIntervalsForSpills(*li, spillIs, loopInfo, *vrm); newIntervals.insert(newIntervals.end(), added.begin(), added.end()); @@ -217,33 +222,31 @@ namespace { /// When a call to spill is placed this spiller will first try to break the /// interval up into its component values (one new interval per value). /// If this fails, or if a call is placed to spill a previously split interval -/// then the spiller falls back on the standard spilling mechanism. +/// then the spiller falls back on the standard spilling mechanism. class SplittingSpiller : public StandardSpiller { public: - SplittingSpiller(MachineFunction *mf, LiveIntervals *lis, - const MachineLoopInfo *loopInfo, VirtRegMap *vrm) - : StandardSpiller(lis, loopInfo, vrm) { - - mri = &mf->getRegInfo(); - tii = mf->getTarget().getInstrInfo(); - tri = mf->getTarget().getRegisterInfo(); + SplittingSpiller(MachineFunctionPass &pass, MachineFunction &mf, + VirtRegMap &vrm) + : StandardSpiller(pass, mf, vrm) { + mri = &mf.getRegInfo(); + tii = mf.getTarget().getInstrInfo(); + tri = mf.getTarget().getRegisterInfo(); } void spill(LiveInterval *li, - std::vector &newIntervals, - SmallVectorImpl &spillIs, - SlotIndex *earliestStart) { + SmallVectorImpl &newIntervals, + SmallVectorImpl &spillIs) { if (worthTryingToSplit(li)) - tryVNISplit(li, earliestStart); + tryVNISplit(li); else - StandardSpiller::spill(li, newIntervals, spillIs, earliestStart); + StandardSpiller::spill(li, newIntervals, spillIs); } private: MachineRegisterInfo *mri; const TargetInstrInfo *tii; - const TargetRegisterInfo *tri; + const TargetRegisterInfo *tri; DenseSet alreadySplit; bool worthTryingToSplit(LiveInterval *li) const { @@ -251,8 +254,7 @@ private: } /// Try to break a LiveInterval into its component values. - std::vector tryVNISplit(LiveInterval *li, - SlotIndex *earliestStart) { + std::vector tryVNISplit(LiveInterval *li) { DEBUG(dbgs() << "Trying VNI split of %reg" << *li << "\n"); @@ -260,42 +262,34 @@ private: SmallVector vnis; std::copy(li->vni_begin(), li->vni_end(), std::back_inserter(vnis)); - + for (SmallVectorImpl::iterator vniItr = vnis.begin(), vniEnd = vnis.end(); vniItr != vniEnd; ++vniItr) { VNInfo *vni = *vniItr; - + // Skip unused VNIs. if (vni->isUnused()) continue; DEBUG(dbgs() << " Extracted Val #" << vni->id << " as "); LiveInterval *splitInterval = extractVNI(li, vni); - + if (splitInterval != 0) { DEBUG(dbgs() << *splitInterval << "\n"); added.push_back(splitInterval); alreadySplit.insert(splitInterval); - if (earliestStart != 0) { - if (splitInterval->beginIndex() < *earliestStart) - *earliestStart = splitInterval->beginIndex(); - } } else { DEBUG(dbgs() << "0\n"); } - } + } DEBUG(dbgs() << "Original LI: " << *li << "\n"); // If there original interval still contains some live ranges - // add it to added and alreadySplit. + // add it to added and alreadySplit. if (!li->empty()) { added.push_back(li); alreadySplit.insert(li); - if (earliestStart != 0) { - if (li->beginIndex() < *earliestStart) - *earliestStart = li->beginIndex(); - } } return added; @@ -312,7 +306,7 @@ private: LiveInterval *newLI = &lis->getOrCreateInterval(newVReg); VNInfo *newVNI = newLI->createValueCopy(vni, lis->getVNInfoAllocator()); - // Start by copying all live ranges in the VN to the new interval. + // Start by copying all live ranges in the VN to the new interval. for (LiveInterval::iterator rItr = li->begin(), rEnd = li->end(); rItr != rEnd; ++rItr) { if (rItr->valno == vni) { @@ -320,7 +314,7 @@ private: } } - // Erase the old VNI & ranges. + // Erase the old VNI & ranges. li->removeValNo(vni); // Collect all current uses of the register belonging to the given VNI. @@ -337,10 +331,9 @@ private: // Insert a copy at the start of the MBB. The range proceeding the // copy will be attached to the original LiveInterval. MachineBasicBlock *defMBB = lis->getMBBFromIndex(newVNI->def); - tii->copyRegToReg(*defMBB, defMBB->begin(), newVReg, li->reg, trc, trc, - DebugLoc()); - MachineInstr *copyMI = defMBB->begin(); - copyMI->addRegisterKilled(li->reg, tri); + MachineInstr *copyMI = BuildMI(*defMBB, defMBB->begin(), DebugLoc(), + tii->get(TargetOpcode::COPY), newVReg) + .addReg(li->reg, RegState::Kill); SlotIndex copyIdx = lis->InsertMachineInstrInMaps(copyMI); VNInfo *phiDefVNI = li->getNextValue(lis->getMBBStartIdx(defMBB), 0, false, lis->getVNInfoAllocator()); @@ -367,8 +360,8 @@ private: newVNI->setIsPHIDef(false); // not a PHI def anymore. newVNI->setIsDefAccurate(true); } else { - // non-PHI def. Rename the def. If it's two-addr that means renaming the use - // and inserting a new copy too. + // non-PHI def. Rename the def. If it's two-addr that means renaming the + // use and inserting a new copy too. MachineInstr *defInst = lis->getInstructionFromIndex(newVNI->def); // We'll rename this now, so we can remove it from uses. uses.erase(defInst); @@ -384,17 +377,16 @@ private: twoAddrUseIsUndef = true; } } - + SlotIndex defIdx = lis->getInstructionIndex(defInst); newVNI->def = defIdx.getDefIndex(); if (isTwoAddr && !twoAddrUseIsUndef) { MachineBasicBlock *defMBB = defInst->getParent(); - tii->copyRegToReg(*defMBB, defInst, newVReg, li->reg, trc, trc, - DebugLoc()); - MachineInstr *copyMI = prior(MachineBasicBlock::iterator(defInst)); + MachineInstr *copyMI = BuildMI(*defMBB, defInst, DebugLoc(), + tii->get(TargetOpcode::COPY), newVReg) + .addReg(li->reg, RegState::Kill); SlotIndex copyIdx = lis->InsertMachineInstrInMaps(copyMI); - copyMI->addRegisterKilled(li->reg, tri); LiveRange *origUseRange = li->getLiveRangeContaining(newVNI->def.getUseIndex()); origUseRange->end = copyIdx.getDefIndex(); @@ -402,9 +394,9 @@ private: true, lis->getVNInfoAllocator()); LiveRange copyRange(copyIdx.getDefIndex(),defIdx.getDefIndex(),copyVNI); newLI->addRange(copyRange); - } + } } - + for (std::set::iterator usesItr = uses.begin(), usesEnd = uses.end(); usesItr != usesEnd; ++usesItr) { @@ -424,7 +416,7 @@ private: // Check if this instr is two address. unsigned useOpIdx = useInst->findRegisterUseOperandIdx(li->reg); bool isTwoAddress = useInst->isRegTiedToDefOperand(useOpIdx); - + // Rename uses (and defs for two-address instrs). for (unsigned i = 0; i < useInst->getNumOperands(); ++i) { MachineOperand &mo = useInst->getOperand(i); @@ -440,10 +432,9 @@ private: // reg. MachineBasicBlock *useMBB = useInst->getParent(); MachineBasicBlock::iterator useItr(useInst); - tii->copyRegToReg(*useMBB, llvm::next(useItr), li->reg, newVReg, trc, trc, - DebugLoc()); - MachineInstr *copyMI = llvm::next(useItr); - copyMI->addRegisterKilled(newVReg, tri); + MachineInstr *copyMI = BuildMI(*useMBB, llvm::next(useItr), DebugLoc(), + tii->get(TargetOpcode::COPY), newVReg) + .addReg(li->reg, RegState::Kill); SlotIndex copyIdx = lis->InsertMachineInstrInMaps(copyMI); // Change the old two-address defined range & vni to start at @@ -471,12 +462,10 @@ private: continue; SlotIndex killIdx = LRI->end; MachineBasicBlock *killMBB = lis->getMBBFromIndex(killIdx); - - tii->copyRegToReg(*killMBB, killMBB->getFirstTerminator(), - li->reg, newVReg, trc, trc, - DebugLoc()); - MachineInstr *copyMI = prior(killMBB->getFirstTerminator()); - copyMI->addRegisterKilled(newVReg, tri); + MachineInstr *copyMI = BuildMI(*killMBB, killMBB->getFirstTerminator(), + DebugLoc(), tii->get(TargetOpcode::COPY), + li->reg) + .addReg(newVReg, RegState::Kill); SlotIndex copyIdx = lis->InsertMachineInstrInMaps(copyMI); // Save the current end. We may need it to add a new range if the @@ -510,20 +499,19 @@ private: namespace llvm { -Spiller *createInlineSpiller(MachineFunction*, - LiveIntervals*, - const MachineLoopInfo*, - VirtRegMap*); +Spiller *createInlineSpiller(MachineFunctionPass &pass, + MachineFunction &mf, + VirtRegMap &vrm); } -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) { default: assert(0 && "unknown spiller"); - case trivial: return new TrivialSpiller(mf, lis, vrm); - case standard: return new StandardSpiller(lis, loopInfo, vrm); - case splitting: return new SplittingSpiller(mf, lis, loopInfo, vrm); - case inline_: return createInlineSpiller(mf, lis, loopInfo, vrm); + case trivial: return new TrivialSpiller(pass, mf, vrm); + case standard: return new StandardSpiller(pass, mf, vrm); + case splitting: return new SplittingSpiller(pass, mf, vrm); + case inline_: return createInlineSpiller(pass, mf, vrm); } }