From b50bb8cf197709b3f49044740044c06d8f314564 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 5 Dec 2007 08:16:32 +0000 Subject: [PATCH] Fix kill info for split intervals. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44609 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveIntervalAnalysis.cpp | 30 ++++++++++++++++++---------- lib/CodeGen/VirtRegMap.cpp | 8 +++++--- lib/CodeGen/VirtRegMap.h | 22 ++++++++++---------- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 5c95eb16d83..cc2298a898c 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -1267,6 +1267,7 @@ addIntervalsForSpills(const LiveInterval &li, if (!TrySplit) return NewLIs; + SmallPtrSet AddedKill; SmallVector Ops; if (NeedStackSlot) { int Id = SpillMBBs.find_first(); @@ -1316,8 +1317,13 @@ addIntervalsForSpills(const LiveInterval &li, } // Else tell the spiller to issue a spill. - if (!Folded) - vrm.addSpillPoint(VReg, MI); + if (!Folded) { + LiveRange *LR = &nI.ranges[nI.ranges.size()-1]; + bool isKill = LR->end == getStoreIndex(index); + vrm.addSpillPoint(VReg, isKill, MI); + if (isKill) + AddedKill.insert(&nI); + } } Id = SpillMBBs.find_next(Id); } @@ -1372,24 +1378,28 @@ addIntervalsForSpills(const LiveInterval &li, // load / rematerialization for us. if (Folded) nI.removeRange(getLoadIndex(index), getUseIndex(index)+1); - else { + else vrm.addRestorePoint(VReg, MI); - LiveRange *LR = &nI.ranges[nI.ranges.size()-1]; - MachineInstr *LastUse = getInstructionFromIndex(getBaseIndex(LR->end)); - int UseIdx = LastUse->findRegisterUseOperandIdx(VReg); - assert(UseIdx != -1); - LastUse->getOperand(UseIdx).setIsKill(); - } } Id = RestoreMBBs.find_next(Id); } - // Finalize spill weights and filter out dead intervals. + // Finalize intervals: add kills, finalize spill weights, and filter out + // dead intervals. std::vector RetNewLIs; for (unsigned i = 0, e = NewLIs.size(); i != e; ++i) { LiveInterval *LI = NewLIs[i]; if (!LI->empty()) { LI->weight /= LI->getSize(); + if (!AddedKill.count(LI)) { + LiveRange *LR = &LI->ranges[LI->ranges.size()-1]; + MachineInstr *LastUse = getInstructionFromIndex(getBaseIndex(LR->end)); + int UseIdx = LastUse->findRegisterUseOperandIdx(LI->reg); + assert(UseIdx != -1); + if (LastUse->getInstrDescriptor()-> + getOperandConstraint(UseIdx, TOI::TIED_TO) == -1) + LastUse->getOperand(UseIdx).setIsKill(); + } RetNewLIs.push_back(LI); } } diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 050f17fe7a1..b8135bfe990 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -977,15 +977,17 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) { // Insert spills here if asked to. if (VRM.isSpillPt(&MI)) { - std::vector &SpillRegs = VRM.getSpillPtSpills(&MI); + std::vector > &SpillRegs = + VRM.getSpillPtSpills(&MI); for (unsigned i = 0, e = SpillRegs.size(); i != e; ++i) { - unsigned VirtReg = SpillRegs[i]; + unsigned VirtReg = SpillRegs[i].first; + bool isKill = SpillRegs[i].second; if (!VRM.getPreSplitReg(VirtReg)) continue; // Split interval spilled again. const TargetRegisterClass *RC = RegMap->getRegClass(VirtReg); unsigned Phys = VRM.getPhys(VirtReg); int StackSlot = VRM.getStackSlot(VirtReg); - MRI->storeRegToStackSlot(MBB, next(MII), Phys, false, StackSlot, RC); + MRI->storeRegToStackSlot(MBB, next(MII), Phys, isKill, StackSlot, RC); MachineInstr *StoreMI = next(MII); DOUT << "Store:\t" << StoreMI; VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod); diff --git a/lib/CodeGen/VirtRegMap.h b/lib/CodeGen/VirtRegMap.h index 61a9738469c..df32a6566a7 100644 --- a/lib/CodeGen/VirtRegMap.h +++ b/lib/CodeGen/VirtRegMap.h @@ -80,7 +80,8 @@ namespace llvm { /// SpillPt2VirtMap - This records the virtual registers which should /// be spilled right after the MachineInstr due to live interval /// splitting. - std::map > SpillPt2VirtMap; + std::map > > + SpillPt2VirtMap; /// RestorePt2VirtMap - This records the virtual registers which should /// be restored right before the MachineInstr due to live interval @@ -216,30 +217,31 @@ namespace llvm { /// @brief returns the virtual registers that should be spilled due to /// splitting right after the specified MachineInstr. - std::vector &getSpillPtSpills(MachineInstr *Pt) { + std::vector > &getSpillPtSpills(MachineInstr *Pt) { return SpillPt2VirtMap[Pt]; } /// @brief records the specified MachineInstr as a spill point for virtReg. - void addSpillPoint(unsigned virtReg, MachineInstr *Pt) { + void addSpillPoint(unsigned virtReg, bool isKill, MachineInstr *Pt) { if (SpillPt2VirtMap.find(Pt) != SpillPt2VirtMap.end()) - SpillPt2VirtMap[Pt].push_back(virtReg); + SpillPt2VirtMap[Pt].push_back(std::make_pair(virtReg, isKill)); else { - std::vector Virts; - Virts.push_back(virtReg); + std::vector > Virts; + Virts.push_back(std::make_pair(virtReg, isKill)); SpillPt2VirtMap.insert(std::make_pair(Pt, Virts)); } } void transferSpillPts(MachineInstr *Old, MachineInstr *New) { - std::map >::iterator I = - SpillPt2VirtMap.find(Old); + std::map > >::iterator + I = SpillPt2VirtMap.find(Old); if (I == SpillPt2VirtMap.end()) return; while (!I->second.empty()) { - unsigned virtReg = I->second.back(); + unsigned virtReg = I->second.back().first; + bool isKill = I->second.back().second; I->second.pop_back(); - addSpillPoint(virtReg, New); + addSpillPoint(virtReg, isKill, New); } SpillPt2VirtMap.erase(I); }