From de4e942faa12a52242915e3334c25f19687f36e2 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sun, 25 Feb 2007 09:51:27 +0000 Subject: [PATCH] A couple of more places where a register liveness has been extended and its last kill should be updated accordingly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34597 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/VirtRegMap.cpp | 62 +++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 4f1230cd207..ceb4acee698 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -254,7 +254,8 @@ class VISIBILITY_HIDDEN AvailableSpills { // SpillSlotsAvailable - This map keeps track of all of the spilled virtual // register values that are still available, due to being loaded or stored to, - // but not invalidated yet. + // but not invalidated yet. It also tracks the instruction that last defined + // or used the register. typedef std::pair SSInfo; std::map SpillSlotsAvailable; @@ -285,6 +286,24 @@ public: } return 0; } + + /// UpdateLastUses - Update the last use information of all stack slots whose + /// values are available in the specific register. + void UpdateLastUse(unsigned PhysReg, MachineInstr *Use) { + std::multimap::iterator I = + PhysRegsAvailable.lower_bound(PhysReg); + while (I != PhysRegsAvailable.end() && I->first == PhysReg) { + int Slot = I->second; + I++; + + std::map::iterator II = SpillSlotsAvailable.find(Slot); + assert(II != SpillSlotsAvailable.end() && "Slot not available!"); + unsigned Val = II->second.first; + assert((Val >> 1) == PhysReg && "Bidirectional map mismatch!"); + SpillSlotsAvailable.erase(Slot); + SpillSlotsAvailable[Slot] = std::make_pair(Val, Use); + } + } /// addAvailable - Mark that the specified stack slot is available in the /// specified physreg. If CanClobber is true, the physreg can be modified at @@ -667,10 +686,12 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) { MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true); if (MOK) { MOK->unsetIsKill(); - if (ti == -1) + if (ti == -1) { // Unless it's the use of a two-address code, transfer the kill // of the reused register to this use. MI.getOperand(i).setIsKill(); + Spills.UpdateLastUse(PhysReg, &MI); + } } // The only technical detail we have is that we don't know that @@ -737,7 +758,20 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) { PhysRegsUsed[DesignatedReg] = true; ReusedOperands.markClobbered(DesignatedReg); MRI->copyRegToReg(MBB, &MI, DesignatedReg, PhysReg, RC); - + + // Extend the live range of the MI that last kill the register if + // necessary. + if (SSMI) { + MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true); + if (MOK) { + MachineInstr *CopyMI = prior(MII); + MachineOperand *MOU = CopyMI->findRegisterUseOperand(PhysReg); + MOU->setIsKill(); + MOK->unsetIsKill(); + Spills.UpdateLastUse(PhysReg, &MI); + } + } + // This invalidates DesignatedReg. Spills.ClobberPhysReg(DesignatedReg); @@ -771,6 +805,10 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) { // Any stores to this stack slot are not dead anymore. MaybeDeadStores.erase(StackSlot); Spills.addAvailable(StackSlot, &MI, PhysReg); + // Assumes this is the last use. IsKill will be unset if reg is reused + // unless it's a two-address operand. + if (TID->getOperandConstraint(i, TOI::TIED_TO) == -1) + MI.getOperand(i).setIsKill(); ++NumLoads; MI.getOperand(i).setReg(PhysReg); DOUT << '\t' << *prior(MII); @@ -802,8 +840,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) { if (FrameIdx == SS) { // If this spill slot is available, turn it into a copy (or nothing) // instead of leaving it as a load! - MachineInstr *Dummy = NULL; - if (unsigned InReg = Spills.getSpillSlotPhysReg(SS, Dummy)) { + MachineInstr *SSMI = NULL; + if (unsigned InReg = Spills.getSpillSlotPhysReg(SS, SSMI)) { DOUT << "Promoted Load To Copy: " << MI; MachineFunction &MF = *MBB.getParent(); if (DestReg != InReg) { @@ -814,7 +852,21 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) { // virtual or needing to clobber any values if it's physical). NextMII = &MI; --NextMII; // backtrack to the copy. + } else + DOUT << "Removing now-noop copy: " << MI; + + // Extend the live range of the MI that last kill the register if + // the next MI reuse it. + MachineOperand *MOK = SSMI->findRegisterUseOperand(InReg, true); + if (MOK && NextMII != MBB.end()) { + MachineOperand *MOU = NextMII->findRegisterUseOperand(InReg); + if (MOU) { + MOU->setIsKill(); + MOK->unsetIsKill(); + Spills.UpdateLastUse(InReg, &(*NextMII)); + } } + VRM.RemoveFromFoldedVirtMap(&MI); MBB.erase(&MI); goto ProcessNextInst;