[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp
Evan Cheng
evan.cheng at apple.com
Sun Feb 25 01:51:44 PST 2007
Changes in directory llvm/lib/CodeGen:
VirtRegMap.cpp updated: 1.99 -> 1.100
---
Log message:
A couple of more places where a register liveness has been extended and its last kill should be updated accordingly.
---
Diffs of the changes: (+57 -5)
VirtRegMap.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 57 insertions(+), 5 deletions(-)
Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.99 llvm/lib/CodeGen/VirtRegMap.cpp:1.100
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.99 Fri Feb 23 15:47:50 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Sun Feb 25 03:51:27 2007
@@ -254,7 +254,8 @@
// 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 @@
}
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 @@
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 @@
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 @@
// 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 @@
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 @@
// 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;
More information about the llvm-commits
mailing list