diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-02-25 09:51:27 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-02-25 09:51:27 +0000 |
commit | de4e942faa12a52242915e3334c25f19687f36e2 (patch) | |
tree | 358dd408e8a44813e5b05baf975b2f1b3b255dc0 /lib/CodeGen/VirtRegMap.cpp | |
parent | 0badfea274f9612780caccbad6e1870f39ed9f40 (diff) | |
download | external_llvm-de4e942faa12a52242915e3334c25f19687f36e2.zip external_llvm-de4e942faa12a52242915e3334c25f19687f36e2.tar.gz external_llvm-de4e942faa12a52242915e3334c25f19687f36e2.tar.bz2 |
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
Diffstat (limited to 'lib/CodeGen/VirtRegMap.cpp')
-rw-r--r-- | lib/CodeGen/VirtRegMap.cpp | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 4f1230c..ceb4ace 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<unsigned, MachineInstr*> SSInfo; std::map<int, SSInfo> 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<unsigned, int>::iterator I = + PhysRegsAvailable.lower_bound(PhysReg); + while (I != PhysRegsAvailable.end() && I->first == PhysReg) { + int Slot = I->second; + I++; + + std::map<int, SSInfo>::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; |