diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 2e6b16b7709..e517cb371e6 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -23,6 +23,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "Support/Statistic.h" #include "Support/Debug.h" +#include "Support/DenseMap.h" #include "Support/STLExtras.h" #include @@ -73,6 +74,7 @@ namespace { class Spiller { typedef std::vector Phys2VirtMap; typedef std::vector PhysFlag; + typedef DenseMap Virt2MI; MachineFunction& mf_; const TargetMachine& tm_; @@ -81,6 +83,7 @@ namespace { const VirtRegMap& vrm_; Phys2VirtMap p2vMap_; PhysFlag dirty_; + Virt2MI lastDef_; public: Spiller(MachineFunction& mf, const VirtRegMap& vrm) @@ -90,7 +93,8 @@ namespace { mri_(*tm_.getRegisterInfo()), vrm_(vrm), p2vMap_(mri_.getNumRegs(), 0), - dirty_(mri_.getNumRegs(), false) { + dirty_(mri_.getNumRegs(), false), + lastDef_() { DEBUG(std::cerr << "********** REWRITE MACHINE CODE **********\n"); DEBUG(std::cerr << "********** Function: " << mf_.getFunction()->getName() << '\n'); @@ -99,11 +103,13 @@ namespace { void eliminateVirtRegs() { for (MachineFunction::iterator mbbi = mf_.begin(), mbbe = mf_.end(); mbbi != mbbe; ++mbbi) { + lastDef_.grow(mf_.getSSARegMap()->getLastVirtReg()); DEBUG(std::cerr << mbbi->getBasicBlock()->getName() << ":\n"); eliminateVirtRegsInMbb(*mbbi); - // clear map and dirty flag + // clear map, dirty flag and last ref p2vMap_.assign(p2vMap_.size(), 0); dirty_.assign(dirty_.size(), false); + lastDef_.clear(); } } @@ -113,11 +119,21 @@ namespace { unsigned physReg) { unsigned virtReg = p2vMap_[physReg]; if (dirty_[physReg] && vrm_.hasStackSlot(virtReg)) { - mri_.storeRegToStackSlot(mbb, mii, physReg, + assert(lastDef_[virtReg] && "virtual register is mapped " + "to a register and but was not defined!"); + MachineBasicBlock::iterator lastDef = lastDef_[virtReg]; + MachineBasicBlock::iterator nextLastRef = next(lastDef); + mri_.storeRegToStackSlot(*lastDef->getParent(), + nextLastRef, + physReg, vrm_.getStackSlot(virtReg), mri_.getRegClass(physReg)); ++numStores; - DEBUG(std::cerr << "*\t"; prior(mii)->print(std::cerr, tm_)); + DEBUG(std::cerr << "\t\tadded: "; + prior(nextLastRef)->print(std::cerr, tm_); + std::cerr << "\t\tafter: "; + lastDef->print(std::cerr, tm_)); + lastDef_[virtReg] = 0; } p2vMap_[physReg] = 0; dirty_[physReg] = false; @@ -145,7 +161,11 @@ namespace { vrm_.getStackSlot(virtReg), mri_.getRegClass(physReg)); ++numLoads; - DEBUG(std::cerr << "*\t"; prior(mii)->print(std::cerr,tm_)); + DEBUG(std::cerr << "\t\tadded: "; + prior(mii)->print(std::cerr,tm_); + std::cerr << "\t\tbefore: "; + mii->print(std::cerr, tm_)); + lastDef_[virtReg] = mii; } } } @@ -160,6 +180,7 @@ namespace { p2vMap_[physReg] = virtReg; dirty_[physReg] = true; + lastDef_[virtReg] = mii; } void eliminateVirtRegsInMbb(MachineBasicBlock& mbb) { @@ -170,11 +191,15 @@ namespace { MachineOperand& op = mii->getOperand(i); if (op.isRegister() && op.getReg() && op.isUse() && MRegisterInfo::isVirtualRegister(op.getReg())) { - unsigned physReg = vrm_.getPhys(op.getReg()); - handleUse(mbb, mii, op.getReg(), physReg); + unsigned virtReg = op.getReg(); + unsigned physReg = vrm_.getPhys(virtReg); + handleUse(mbb, mii, virtReg, physReg); mii->SetMachineOperandReg(i, physReg); // mark as dirty if this is def&use - if (op.isDef()) dirty_[physReg] = true; + if (op.isDef()) { + dirty_[physReg] = true; + lastDef_[virtReg] = mii; + } } }