aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/VirtRegMap.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2007-02-25 09:51:27 +0000
committerEvan Cheng <evan.cheng@apple.com>2007-02-25 09:51:27 +0000
commitde4e942faa12a52242915e3334c25f19687f36e2 (patch)
tree358dd408e8a44813e5b05baf975b2f1b3b255dc0 /lib/CodeGen/VirtRegMap.cpp
parent0badfea274f9612780caccbad6e1870f39ed9f40 (diff)
downloadexternal_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.cpp62
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;