[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-03-30 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.107 -> 1.108
---
Log message:

Don't add the same MI to register reuse "last def/use" twice if it reads the
register more than once.

---
Diffs of the changes:  (+4 -1)

 VirtRegMap.cpp |5 -
 1 files changed, 4 insertions(+), 1 deletion(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.107 
llvm/lib/CodeGen/VirtRegMap.cpp:1.108
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.107   Mon Mar 26 19:48:28 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Mar 30 15:21:35 2007
@@ -316,7 +316,9 @@
   assert(II != SpillSlotsAvailable.end() && "Slot not available!");
   unsigned Val = II->second.first;
   assert((Val >> 1) == PhysReg && "Bidirectional map mismatch!");
-  II->second.second.push_back(Use);
+  // This can be true if there are multiple uses of the same register.
+  if (II->second.second.back() != Use)
+II->second.second.push_back(Use);
 }
   }
   
@@ -1117,6 +1119,7 @@
   if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
 ++NumDCE;
 DOUT << "Removing now-noop copy: " << MI;
+Spills.removeLastUse(Src, &MI);
 MBB.erase(&MI);
 VRM.RemoveFromFoldedVirtMap(&MI);
 goto ProcessNextInst;



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-03-26 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.106 -> 1.107
---
Log message:

Don't call getOperandConstraint() if operand index is greater than
TID->numOperands.

---
Diffs of the changes:  (+2 -1)

 VirtRegMap.cpp |3 ++-
 1 files changed, 2 insertions(+), 1 deletion(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.106 
llvm/lib/CodeGen/VirtRegMap.cpp:1.107
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.106   Mon Mar 26 17:40:42 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Mon Mar 26 19:48:28 2007
@@ -965,7 +965,8 @@
   if (WasKill) {
 const TargetInstrDescriptor *NTID =
   NextMII->getInstrDescriptor();
-if (NTID->getOperandConstraint(UIdx, TOI::TIED_TO) == -1)
+if (UIdx >= NTID->numOperands ||
+NTID->getOperandConstraint(UIdx, TOI::TIED_TO) == -1)
   MOU.setIsKill();
   }
   Spills.addLastUse(InReg, &(*NextMII));



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp LiveIntervalAnalysis.cpp

2007-03-26 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.105 -> 1.106
LiveIntervalAnalysis.cpp updated: 1.227 -> 1.228
---
Log message:

Fix for PR1266: http://llvm.org/PR1266 . Don't mark a two address operand 
IsKill.

---
Diffs of the changes:  (+33 -22)

 LiveIntervalAnalysis.cpp |6 ++---
 VirtRegMap.cpp   |   49 ---
 2 files changed, 33 insertions(+), 22 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.105 
llvm/lib/CodeGen/VirtRegMap.cpp:1.106
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.105   Tue Mar 20 03:13:50 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Mon Mar 26 17:40:42 2007
@@ -754,10 +754,11 @@
   // necessary.
   bool WasKill = false;
   if (SSMI) {
-MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true);
-if (MOK) {
-  WasKill = MOK->isKill();
-  MOK->unsetIsKill();
+int UIdx = SSMI->findRegisterUseOperand(PhysReg, true);
+if (UIdx != -1) {
+  MachineOperand &MOK = SSMI->getOperand(UIdx);
+  WasKill = MOK.isKill();
+  MOK.unsetIsKill();
 }
   }
   if (ti == -1) {
@@ -840,17 +841,20 @@
 // necessary.
 bool WasKill = false;
 if (SSMI) {
-  MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true);
-  if (MOK) {
-WasKill = MOK->isKill();
-MOK->unsetIsKill();
+  int UIdx = SSMI->findRegisterUseOperand(PhysReg, true);
+  if (UIdx != -1) {
+MachineOperand &MOK = SSMI->getOperand(UIdx);
+WasKill = MOK.isKill();
+MOK.unsetIsKill();
   }
 }
 MachineInstr *CopyMI = prior(MII);
 if (WasKill) {
   // Transfer kill to the next use.
-  MachineOperand *MOU = CopyMI->findRegisterUseOperand(PhysReg);
-  MOU->setIsKill();
+  int UIdx = CopyMI->findRegisterUseOperand(PhysReg);
+  assert(UIdx != -1);
+  MachineOperand &MOU = CopyMI->getOperand(UIdx);
+  MOU.setIsKill();
 }
 Spills.addLastUse(PhysReg, CopyMI);
 
@@ -945,18 +949,25 @@
   // extended. Remove its kill.
   bool WasKill = false;
   if (SSMI) {
-MachineOperand *MOK = SSMI->findRegisterUseOperand(InReg, 
true);
-if (MOK) {
-  WasKill = MOK->isKill();
-  MOK->unsetIsKill();
+int UIdx = SSMI->findRegisterUseOperand(InReg, true);
+if (UIdx != -1) {
+  MachineOperand &MOK = SSMI->getOperand(UIdx);
+  WasKill = MOK.isKill();
+  MOK.unsetIsKill();
 }
   }
   if (NextMII != MBB.end()) {
-// If NextMII uses InReg (must be the copy?), mark it killed.
-MachineOperand *MOU = NextMII->findRegisterUseOperand(InReg);
-if (MOU) {
-  if (WasKill)
-MOU->setIsKill();
+// If NextMII uses InReg and the use is not a two address
+// operand, mark it killed.
+int UIdx = NextMII->findRegisterUseOperand(InReg);
+if (UIdx != -1) {
+  MachineOperand &MOU = NextMII->getOperand(UIdx);
+  if (WasKill) {
+const TargetInstrDescriptor *NTID =
+  NextMII->getInstrDescriptor();
+if (NTID->getOperandConstraint(UIdx, TOI::TIED_TO) == -1)
+  MOU.setIsKill();
+  }
   Spills.addLastUse(InReg, &(*NextMII));
 }
   }


Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.227 
llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.228
--- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.227 Wed Mar 21 20:26:05 2007
+++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp   Mon Mar 26 17:40:42 2007
@@ -854,9 +854,9 @@
 
   // If the source instruction was killing the source register before the
   // merge, unset the isKill marker given the live range has been extended.
-  MachineOperand *MOK = ValLREndInst->findRegisterUseOperand(IntB.reg, true);
-  if (MOK)
-MOK->unsetIsKill();
+  int UIdx = ValLREndInst->findRegisterUseOperand(IntB.reg, true);
+  if (UIdx != -1)
+ValLREndInst->getOperand(UIdx).unsetIsKill();
   
   // Finally, delete the copy instruction.
   RemoveMachineInstrFromMaps(CopyMI);



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-03-02 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.103 -> 1.104
---
Log message:

Only propagate IsKill if the last use is a kill.

---
Diffs of the changes:  (+22 -8)

 VirtRegMap.cpp |   30 ++
 1 files changed, 22 insertions(+), 8 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.103 
llvm/lib/CodeGen/VirtRegMap.cpp:1.104
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.103   Fri Mar  2 02:52:00 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Sat Mar  3 00:32:37 2007
@@ -703,15 +703,19 @@
 
   // Extend the live range of the MI that last kill the register if
   // necessary.
+  bool WasKill = false;
   if (SSMI) {
 MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true);
-if (MOK)
+if (MOK) {
+  WasKill = MOK->isKill();
   MOK->unsetIsKill();
+}
   }
   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();
+if (WasKill)
+  MI.getOperand(i).setIsKill();
 Spills.addLastUse(PhysReg, &MI);
   }
 
@@ -782,15 +786,21 @@
 
 // Extend the live range of the MI that last kill the register if
 // necessary.
+bool WasKill = false;
 if (SSMI) {
   MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true);
-  if (MOK)
+  if (MOK) {
+WasKill = MOK->isKill();
 MOK->unsetIsKill();
+  }
 }
 MachineInstr *CopyMI = prior(MII);
-MachineOperand *MOU = CopyMI->findRegisterUseOperand(PhysReg);
-MOU->setIsKill();
-Spills.addLastUse(PhysReg, &MI);
+if (WasKill) {
+  // Transfer kill to the next use.
+  MachineOperand *MOU = CopyMI->findRegisterUseOperand(PhysReg);
+  MOU->setIsKill();
+}
+Spills.addLastUse(PhysReg, CopyMI);
 
 // This invalidates DesignatedReg.
 Spills.ClobberPhysReg(DesignatedReg);
@@ -877,16 +887,20 @@
 
   // Either way, the live range of the last kill of InReg has been
   // extended. Remove its kill.
+  bool WasKill = false;
   if (SSMI) {
 MachineOperand *MOK = SSMI->findRegisterUseOperand(InReg, 
true);
-if (MOK)
+if (MOK) {
+  WasKill = MOK->isKill();
   MOK->unsetIsKill();
+}
   }
   if (NextMII != MBB.end()) {
 // If NextMII uses InReg (must be the copy?), mark it killed.
 MachineOperand *MOU = NextMII->findRegisterUseOperand(InReg);
 if (MOU) {
-  MOU->setIsKill();
+  if (WasKill)
+MOU->setIsKill();
   Spills.addLastUse(InReg, &(*NextMII));
 }
   }



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-03-02 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.102 -> 1.103
---
Log message:

- Keep track all def and uses of stack slot available in register.
- Available value use may be deleted (e.g. noop move).

---
Diffs of the changes:  (+51 -28)

 VirtRegMap.cpp |   79 -
 1 files changed, 51 insertions(+), 28 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.102 
llvm/lib/CodeGen/VirtRegMap.cpp:1.103
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.102   Thu Mar  1 23:41:42 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Mar  2 02:52:00 2007
@@ -254,9 +254,9 @@
 
   // 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. It also tracks the instruction that last defined
+  // but not invalidated yet. It also tracks the instructions that defined
   // or used the register.
-  typedef std::pair SSInfo;
+  typedef std::pair > SSInfo;
   std::map SpillSlotsAvailable;
 
   // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating
@@ -281,15 +281,16 @@
   unsigned getSpillSlotPhysReg(int Slot, MachineInstr *&SSMI) const {
 std::map::const_iterator I = SpillSlotsAvailable.find(Slot);
 if (I != SpillSlotsAvailable.end()) {
-  SSMI = I->second.second;
+  if (!I->second.second.empty())
+SSMI = I->second.second.back();
   return I->second.first >> 1;  // Remove the CanClobber bit.
 }
 return 0;
   }
 
-  /// UpdateLastUses - Update the last use information of all stack slots whose
+  /// addLastUse - Add the last use information of all stack slots whose
   /// values are available in the specific register.
-  void UpdateLastUse(unsigned PhysReg, MachineInstr *Use) {
+  void addLastUse(unsigned PhysReg, MachineInstr *Use) {
 std::multimap::iterator I =
   PhysRegsAvailable.lower_bound(PhysReg);
 while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
@@ -300,8 +301,25 @@
   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);
+  II->second.second.push_back(Use);
+}
+  }
+  
+  /// removeLastUse - Remove the last use information of all stack slots whose
+  /// values are available in the specific register.
+  void removeLastUse(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!");
+  if (II->second.second.back() == Use)
+II->second.second.pop_back();
 }
   }
   
@@ -315,8 +333,10 @@
 ModifyStackSlot(Slot);
 
 PhysRegsAvailable.insert(std::make_pair(Reg, Slot));
+std::vector DefUses;
+DefUses.push_back(MI);
 SpillSlotsAvailable[Slot] =
-  std::make_pair((Reg << 1) | (unsigned)CanClobber, MI);
+  std::make_pair((Reg << 1) | (unsigned)CanClobber, DefUses);
   
 DOUT << "Remembering SS#" << Slot << " in physreg "
  << MRI->getName(Reg) << "\n";
@@ -683,15 +703,16 @@
 
   // Extend the live range of the MI that last kill the register if
   // necessary.
-  MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true);
-  if (MOK) {
-MOK->unsetIsKill();
-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);
-}
+  if (SSMI) {
+MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true);
+if (MOK)
+  MOK->unsetIsKill();
+  }
+  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.addLastUse(PhysReg, &MI);
   }
 
   // The only technical detail we have is that we don't know that
@@ -763,14 +784,13 @@
 // necessary.
 if (SSMI) {
   MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true);
-  if (MOK) {
-MachineInstr *CopyMI = prior(MII);
-MachineOperand *MOU = CopyMI->findRegisterUseOperand(PhysReg);
-MOU->setIsKill();
+  if (MOK)
 

[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-03-01 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.101 -> 1.102
---
Log message:

Invalidate last use of a reused register if the use is a deleted noop copy.

---
Diffs of the changes:  (+1 -0)

 VirtRegMap.cpp |1 +
 1 files changed, 1 insertion(+)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.101 
llvm/lib/CodeGen/VirtRegMap.cpp:1.102
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.101   Wed Feb 28 20:27:30 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Mar  1 23:41:42 2007
@@ -937,6 +937,7 @@
 DOUT << "Removing now-noop copy: " << MI;
 MBB.erase(&MI);
 VRM.RemoveFromFoldedVirtMap(&MI);
+Spills.UpdateLastUse(Src, NULL);
 Spills.disallowClobberPhysReg(VirtReg);
 goto ProcessNextInst;
   }



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-02-28 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.100 -> 1.101
---
Log message:

A restore is promoted to copy (or deleted entirely), remove the kill from the 
last use of the targetted register.

---
Diffs of the changes:  (+4 -3)

 VirtRegMap.cpp |7 ---
 1 files changed, 4 insertions(+), 3 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.100 
llvm/lib/CodeGen/VirtRegMap.cpp:1.101
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.100   Sun Feb 25 03:51:27 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Wed Feb 28 20:27:30 2007
@@ -855,14 +855,15 @@
   } 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.
+  // Either way, the live range of the last kill of InReg has been
+  // extended. Remove its kill.
   MachineOperand *MOK = SSMI->findRegisterUseOperand(InReg, true);
   if (MOK && NextMII != MBB.end()) {
+MOK->unsetIsKill();
+// If NextMII uses InReg (must be the copy?), mark it killed.
 MachineOperand *MOU = NextMII->findRegisterUseOperand(InReg);
 if (MOU) {
   MOU->setIsKill();
-  MOK->unsetIsKill();
   Spills.UpdateLastUse(InReg, &(*NextMII));
 }
   }



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-02-25 Thread Evan Cheng


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.99Fri 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 SSInfo;
   std::map 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::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 @@
   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);
+

[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-02-23 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.98 -> 1.99
---
Log message:

Reuse extends the liveness of a register. Transfer the kill to the operand that 
reuse it.

---
Diffs of the changes:  (+6 -1)

 VirtRegMap.cpp |7 ++-
 1 files changed, 6 insertions(+), 1 deletion(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.98 
llvm/lib/CodeGen/VirtRegMap.cpp:1.99
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.98Thu Feb 22 19:13:26 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 23 15:47:50 2007
@@ -665,8 +665,13 @@
   // Extend the live range of the MI that last kill the register if
   // necessary.
   MachineOperand *MOK = SSMI->findRegisterUseOperand(PhysReg, true);
-  if (MOK)
+  if (MOK) {
 MOK->unsetIsKill();
+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();
+  }
 
   // The only technical detail we have is that we don't know that
   // PhysReg won't be clobbered by a reloaded stack slot that occurs



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-02-22 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.97 -> 1.98
---
Log message:

A spill kills the register being stored. But it is later being reused by 
spiller, its live range has to be extended.

---
Diffs of the changes:  (+39 -25)

 VirtRegMap.cpp |   64 ++---
 1 files changed, 39 insertions(+), 25 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.97 
llvm/lib/CodeGen/VirtRegMap.cpp:1.98
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.97Tue Feb 20 20:22:03 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 22 19:13:26 2007
@@ -255,7 +255,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.
-  std::map SpillSlotsAvailable;
+  typedef std::pair SSInfo;
+  std::map SpillSlotsAvailable;
 
   // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating
   // which stack slot values are currently held by a physreg.  This is used to
@@ -270,27 +271,33 @@
 : MRI(mri), TII(tii) {
   }
   
+  const MRegisterInfo *getRegInfo() const { return MRI; }
+
   /// getSpillSlotPhysReg - If the specified stack slot is available in a 
-  /// physical register, return that PhysReg, otherwise return 0.
-  unsigned getSpillSlotPhysReg(int Slot) const {
-std::map::const_iterator I = SpillSlotsAvailable.find(Slot);
-if (I != SpillSlotsAvailable.end())
-  return I->second >> 1;  // Remove the CanClobber bit.
+  /// physical register, return that PhysReg, otherwise return 0. It also
+  /// returns by reference the instruction that either defines or last uses
+  /// the register.
+  unsigned getSpillSlotPhysReg(int Slot, MachineInstr *&SSMI) const {
+std::map::const_iterator I = SpillSlotsAvailable.find(Slot);
+if (I != SpillSlotsAvailable.end()) {
+  SSMI = I->second.second;
+  return I->second.first >> 1;  // Remove the CanClobber bit.
+}
 return 0;
   }
   
-  const MRegisterInfo *getRegInfo() const { return MRI; }
-
   /// addAvailable - Mark that the specified stack slot is available in the
   /// specified physreg.  If CanClobber is true, the physreg can be modified at
   /// any time without changing the semantics of the program.
-  void addAvailable(int Slot, unsigned Reg, bool CanClobber = true) {
+  void addAvailable(int Slot, MachineInstr *MI, unsigned Reg,
+bool CanClobber = true) {
 // If this stack slot is thought to be available in some other physreg, 
 // remove its record.
 ModifyStackSlot(Slot);
 
 PhysRegsAvailable.insert(std::make_pair(Reg, Slot));
-SpillSlotsAvailable[Slot] = (Reg << 1) | (unsigned)CanClobber;
+SpillSlotsAvailable[Slot] =
+  std::make_pair((Reg << 1) | (unsigned)CanClobber, MI);
   
 DOUT << "Remembering SS#" << Slot << " in physreg "
  << MRI->getName(Reg) << "\n";
@@ -301,7 +308,7 @@
   /// stack slot must be available in a physreg for this query to make sense.
   bool canClobberPhysReg(int Slot) const {
 assert(SpillSlotsAvailable.count(Slot) && "Slot not available!");
-return SpillSlotsAvailable.find(Slot)->second & 1;
+return SpillSlotsAvailable.find(Slot)->second.first & 1;
   }
   
   /// disallowClobberPhysReg - Unset the CanClobber bit of the specified
@@ -330,9 +337,9 @@
   while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
 int Slot = I->second;
 I++;
-assert((SpillSlotsAvailable[Slot] >> 1) == PhysReg &&
+assert((SpillSlotsAvailable[Slot].first >> 1) == PhysReg &&
"Bidirectional map mismatch!");
-SpillSlotsAvailable[Slot] &= ~1;
+SpillSlotsAvailable[Slot].first &= ~1;
 DOUT << "PhysReg " << MRI->getName(PhysReg)
  << " copied, it is available for use but can no longer be modified\n";
   }
@@ -355,7 +362,7 @@
   while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
 int Slot = I->second;
 PhysRegsAvailable.erase(I++);
-assert((SpillSlotsAvailable[Slot] >> 1) == PhysReg &&
+assert((SpillSlotsAvailable[Slot].first >> 1) == PhysReg &&
"Bidirectional map mismatch!");
 SpillSlotsAvailable.erase(Slot);
 DOUT << "PhysReg " << MRI->getName(PhysReg)
@@ -376,9 +383,9 @@
 /// changes.  This removes information about which register the previous value
 /// for this slot lives in (as the previous value is dead now).
 void AvailableSpills::ModifyStackSlot(int Slot) {
-  std::map::iterator It = SpillSlotsAvailable.find(Slot);
+  std::map::iterator It = SpillSlotsAvailable.find(Slot);
   if (It == SpillSlotsAvailable.end()) return;
-  unsigned Reg = It->second >> 1;
+  unsigned Reg = It->second.first >> 1;
   SpillSlotsAvailable.erase(It);
   
   // This register may hold the value of multiple stack slots, only remove this
@@ -514,7 +521,7 @@
 
 MI->getOperand(NewOp.Operand).setReg(Ne

[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-02-20 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.96 -> 1.97
---
Log message:

Use BitVector instead. No functionality change.

---
Diffs of the changes:  (+5 -8)

 VirtRegMap.cpp |   13 +
 1 files changed, 5 insertions(+), 8 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.96 
llvm/lib/CodeGen/VirtRegMap.cpp:1.97
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.96Mon Feb 19 19:29:10 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Tue Feb 20 20:22:03 2007
@@ -27,6 +27,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
@@ -423,14 +424,10 @@
   class VISIBILITY_HIDDEN ReuseInfo {
 MachineInstr &MI;
 std::vector Reuses;
-bool *PhysRegsClobbered;
+BitVector PhysRegsClobbered;
   public:
 ReuseInfo(MachineInstr &mi, const MRegisterInfo *mri) : MI(mi) {
-  PhysRegsClobbered = new bool[mri->getNumRegs()];
-  std::fill(PhysRegsClobbered, PhysRegsClobbered+mri->getNumRegs(), false);
-}
-~ReuseInfo() {
-  delete[] PhysRegsClobbered;
+  PhysRegsClobbered.resize(mri->getNumRegs());
 }
 
 bool hasReuses() const {
@@ -452,11 +449,11 @@
 }
 
 void markClobbered(unsigned PhysReg) {
-  PhysRegsClobbered[PhysReg] = true;
+  PhysRegsClobbered.set(PhysReg);
 }
 
 bool isClobbered(unsigned PhysReg) const {
-  return PhysRegsClobbered[PhysReg];
+  return PhysRegsClobbered.test(PhysReg);
 }
 
 /// GetRegForReload - We are about to emit a reload into PhysReg.  If there



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-02-19 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.95 -> 1.96
---
Log message:

Dead code.

---
Diffs of the changes:  (+0 -6)

 VirtRegMap.cpp |6 --
 1 files changed, 6 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.95 
llvm/lib/CodeGen/VirtRegMap.cpp:1.96
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.95Thu Feb  8 00:04:54 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Mon Feb 19 19:29:10 2007
@@ -233,12 +233,6 @@
 }
   private:
 void RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM);
-void ClobberPhysReg(unsigned PR, std::map &SpillSlots,
-std::multimap &PhysRegs);
-void ClobberPhysRegOnly(unsigned PR, std::map &SpillSlots,
-std::multimap &PhysRegs);
-void ModifyStackSlot(int Slot, std::map &SpillSlots,
- std::multimap &PhysRegs);
   };
 }
 



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-02-07 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.94 -> 1.95
---
Log message:

Fixed a long standing spiller bug that's exposed by Thumb:

The code sequence before the spiller is something like:
 = tMOVrr
%reg1117 = tMOVrr
%reg1078 = tLSLri %reg1117, 2

The it starts spilling:
%r0 = tRestore , 0
%r1 = tRestore , 0
%r1 = tMOVrr %r1
tSpill %r1, , 0
%reg1078 = tLSLri %reg1117, 2

It restores the value while processing the first tMOVrr. At this point, the
spiller remembers fi#5 is available in %r0. Next it processes the second move.
It restores the source before the move and spills the result afterwards. The
move becomes a noop and is deleted. However, a spill has been inserted and that
should invalidate reuse of %r0 for fi#5 and add reuse of %r1 for fi#5.
Therefore, %reg1117 (which is also assigned fi#5) should get %r1, not %r0.


---
Diffs of the changes:  (+13 -13)

 VirtRegMap.cpp |   26 +-
 1 files changed, 13 insertions(+), 13 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.94 
llvm/lib/CodeGen/VirtRegMap.cpp:1.95
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.94Mon Jan 22 18:59:48 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb  8 00:04:54 2007
@@ -923,19 +923,6 @@
 DOUT << "Store:\t" << *next(MII);
 MI.getOperand(i).setReg(PhysReg);
 
-// Check to see if this is a noop copy.  If so, eliminate the
-// instruction before considering the dest reg to be changed.
-{
-  unsigned Src, Dst;
-  if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
-++NumDCE;
-DOUT << "Removing now-noop copy: " << MI;
-MBB.erase(&MI);
-VRM.RemoveFromFoldedVirtMap(&MI);
-goto ProcessNextInst;
-  }
-}
-
 // If there is a dead store to this stack slot, nuke it now.
 MachineInstr *&LastStore = MaybeDeadStores[StackSlot];
 if (LastStore) {
@@ -953,6 +940,19 @@
 Spills.ClobberPhysReg(PhysReg);
 Spills.addAvailable(StackSlot, PhysReg);
 ++NumStores;
+
+// Check to see if this is a noop copy.  If so, eliminate the
+// instruction before considering the dest reg to be changed.
+{
+  unsigned Src, Dst;
+  if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
+++NumDCE;
+DOUT << "Removing now-noop copy: " << MI;
+MBB.erase(&MI);
+VRM.RemoveFromFoldedVirtMap(&MI);
+goto ProcessNextInst;
+  }
+}
   }
 }
   ProcessNextInst:



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-01-22 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.93 -> 1.94
---
Log message:

Switch this to use SmallSet to avoid mallocs in the common case.


---
Diffs of the changes:  (+3 -3)

 VirtRegMap.cpp |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.93 
llvm/lib/CodeGen/VirtRegMap.cpp:1.94
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.93Fri Jan 19 16:40:14 2007
+++ llvm/lib/CodeGen/VirtRegMap.cpp Mon Jan 22 18:59:48 2007
@@ -29,8 +29,8 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallSet.h"
 #include 
-#include 
 using namespace llvm;
 
 STATISTIC(NumSpills, "Number of register spills");
@@ -471,7 +471,7 @@
 unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
  AvailableSpills &Spills,
  std::map &MaybeDeadStores,
- std::set &Rejected) {
+ SmallSet &Rejected) {
   if (Reuses.empty()) return PhysReg;  // This is most often empty.
 
   for (unsigned ro = 0, e = Reuses.size(); ro != e; ++ro) {
@@ -553,7 +553,7 @@
 unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
  AvailableSpills &Spills,
  std::map &MaybeDeadStores) {
-  std::set Rejected;
+  SmallSet Rejected;
   return GetRegForReload(PhysReg, MI, Spills, MaybeDeadStores, Rejected);
 }
   };



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2007-01-19 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.92 -> 1.93
---
Log message:

GetRegForReload() now keeps track which registers have been considered and 
rejected during its quest to find a suitable reload register. This avoids an 
infinite loop in case like this:
  t1 := op t2, t3   


  t2 <- assigned r0 for use by the reload but ended up reuse r1 


  t3 <- assigned r1 for use by the reload but ended up reuse r0 

 
  t1 <- desires r1  

 
sees r1 is taken by t2, tries t2's reload register r0   

 
sees r0 is taken by t3, tries t3's reload register r1   

 
sees r1 is taken by t2, tries t2's reload register r0 ...

---
Diffs of the changes:  (+32 -8)

 VirtRegMap.cpp |   40 
 1 files changed, 32 insertions(+), 8 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.92 
llvm/lib/CodeGen/VirtRegMap.cpp:1.93
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.92Tue Dec 19 16:41:21 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Jan 19 16:40:14 2007
@@ -30,6 +30,7 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/STLExtras.h"
 #include 
+#include 
 using namespace llvm;
 
 STATISTIC(NumSpills, "Number of register spills");
@@ -469,18 +470,23 @@
 /// a new register to use, or evict the previous reload and use this reg. 
 unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
  AvailableSpills &Spills,
- std::map &MaybeDeadStores) {
+ std::map &MaybeDeadStores,
+ std::set &Rejected) {
   if (Reuses.empty()) return PhysReg;  // This is most often empty.
 
   for (unsigned ro = 0, e = Reuses.size(); ro != e; ++ro) {
 ReusedOp &Op = Reuses[ro];
 // If we find some other reuse that was supposed to use this register
 // exactly for its reload, we can change this reload to use ITS reload
-// register.
-if (Op.PhysRegReused == PhysReg) {
+// register. That is, unless its reload register has already been
+// considered and subsequently rejected because it has also been reused
+// by another operand.
+if (Op.PhysRegReused == PhysReg &&
+Rejected.count(Op.AssignedPhysReg) == 0) {
   // Yup, use the reload register that we didn't use before.
-  unsigned NewReg = Op.AssignedPhysReg;  
-  return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores);
+  unsigned NewReg = Op.AssignedPhysReg;
+  Rejected.insert(PhysReg);
+  return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores, 
Rejected);
 } else {
   // Otherwise, we might also have a problem if a previously reused
   // value aliases the new register.  If so, codegen the previous 
reload
@@ -505,7 +511,7 @@
 // register could hold a reuse.  Check to see if it conflicts or
 // would prefer us to use a different register.
 unsigned NewPhysReg = GetRegForReload(NewOp.AssignedPhysReg,
-  MI, Spills, MaybeDeadStores);
+ MI, Spills, MaybeDeadStores, 
Rejected);
 
 MRI->loadRegFromStackSlot(*MBB, MI, NewPhysReg,
   NewOp.StackSlot, AliasRC);
@@ -532,6 +538,24 @@
   }
   return PhysReg;
 }
+
+/// GetRegForReload - Helper for the above GetRegForReload(). Add a
+/// 'Rejected' set to remember which registers have been considered and
+/// rejected for the reload. This avoids infinite looping in case like
+/// this:
+/// t1 := op t2, t3
+/// t2 <- assigned r0 for use by the reload but ended up reuse r1
+/// t3 <- assigned r1 for use by the reload but ended up reuse r0
+/// t1 <- desires r1
+///   sees r1 is taken by t2, tries t2's reload register r0
+///   sees r0 is taken by t3, tries t3's reload register r1
+///   sees r1 is taken by t2, tries t2's reload register r0 ...
+unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
+ 

[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-12-14 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.89 -> 1.90
---
Log message:

Minor clean up.

---
Diffs of the changes:  (+3 -2)

 VirtRegMap.cpp |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.89 
llvm/lib/CodeGen/VirtRegMap.cpp:1.90
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.89Thu Dec 14 01:54:05 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Dec 15 00:41:01 2006
@@ -573,7 +573,8 @@
 
 // Loop over all of the implicit defs, clearing them from our available
 // sets.
-const unsigned *ImpDef = TII->getImplicitDefs(MI.getOpcode());
+const TargetInstrDescriptor *TID = MI.getInstrDescriptor();
+const unsigned *ImpDef = TID->ImplicitDefs;
 if (ImpDef) {
   for ( ; *ImpDef; ++ImpDef) {
 PhysRegsUsed[*ImpDef] = true;
@@ -626,7 +627,7 @@
 // aren't allowed to modify the reused register.  If none of these 
cases
 // apply, reuse it.
 bool CanReuse = true;
-int ti = MI.getInstrDescriptor()->getOperandConstraint(i, 
TOI::TIED_TO);
+int ti = TID->getOperandConstraint(i, TOI::TIED_TO);
 if (ti != -1 &&
 MI.getOperand(ti).isReg() && 
 MI.getOperand(ti).getReg() == VirtReg) {



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-12-13 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.88 -> 1.89
---
Log message:

Fix a long-standing spiller bug:
If a spillslot value is available in a register, and there is a noop copy that
targets that register, the spiller correctly decide not to invalidate the
spillslot register.

However, even though the noop copy does not clobbers the value. It does start a
new intersecting live range. That means the spillslot register is available for
use but should not be reused for a two-address instruction modref operand which
would clobber the new live range.

When we remove the noop copy, update the available information by clearing the
canClobber bit.


---
Diffs of the changes:  (+35 -1)

 VirtRegMap.cpp |   36 +++-
 1 files changed, 35 insertions(+), 1 deletion(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.88 
llvm/lib/CodeGen/VirtRegMap.cpp:1.89
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.88Fri Dec  8 12:45:48 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Dec 14 01:54:05 2006
@@ -272,6 +272,8 @@
   // invalidate entries in SpillSlotsAvailable when a physreg is modified.
   std::multimap PhysRegsAvailable;
   
+  void disallowClobberPhysRegOnly(unsigned PhysReg);
+
   void ClobberPhysRegOnly(unsigned PhysReg);
 public:
   AvailableSpills(const MRegisterInfo *mri, const TargetInstrInfo *tii)
@@ -303,7 +305,7 @@
 DOUT << "Remembering SS#" << Slot << " in physreg "
  << MRI->getName(Reg) << "\n";
   }
-  
+
   /// canClobberPhysReg - Return true if the spiller is allowed to change the 
   /// value of the specified stackslot register if it desires.  The specified
   /// stack slot must be available in a physreg for this query to make sense.
@@ -312,6 +314,11 @@
 return SpillSlotsAvailable.find(Slot)->second & 1;
   }
   
+  /// disallowClobberPhysReg - Unset the CanClobber bit of the specified
+  /// stackslot register. The register is still available but is no longer
+  /// allowed to be modifed.
+  void disallowClobberPhysReg(unsigned PhysReg);
+  
   /// ClobberPhysReg - This is called when the specified physreg changes
   /// value.  We use this to invalidate any info about stuff we thing lives in
   /// it and any of its aliases.
@@ -324,6 +331,32 @@
 };
 }
 
+/// disallowClobberPhysRegOnly - Unset the CanClobber bit of the specified
+/// stackslot register. The register is still available but is no longer
+/// allowed to be modifed.
+void AvailableSpills::disallowClobberPhysRegOnly(unsigned PhysReg) {
+  std::multimap::iterator I =
+PhysRegsAvailable.lower_bound(PhysReg);
+  while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
+int Slot = I->second;
+I++;
+assert((SpillSlotsAvailable[Slot] >> 1) == PhysReg &&
+   "Bidirectional map mismatch!");
+SpillSlotsAvailable[Slot] &= ~1;
+DOUT << "PhysReg " << MRI->getName(PhysReg)
+ << " copied, it is available for use but can no longer be modified\n";
+  }
+}
+
+/// disallowClobberPhysReg - Unset the CanClobber bit of the specified
+/// stackslot register and its aliases. The register and its aliases may
+/// still available but is no longer allowed to be modifed.
+void AvailableSpills::disallowClobberPhysReg(unsigned PhysReg) {
+  for (const unsigned *AS = MRI->getAliasSet(PhysReg); *AS; ++AS)
+disallowClobberPhysRegOnly(*AS);
+  disallowClobberPhysRegOnly(PhysReg);
+}
+
 /// ClobberPhysRegOnly - This is called when the specified physreg changes
 /// value.  We use this to invalidate any info about stuff we thing lives in 
it.
 void AvailableSpills::ClobberPhysRegOnly(unsigned PhysReg) {
@@ -822,6 +855,7 @@
 DOUT << "Removing now-noop copy: " << MI;
 MBB.erase(&MI);
 VRM.RemoveFromFoldedVirtMap(&MI);
+Spills.disallowClobberPhysReg(VirtReg);
 goto ProcessNextInst;
   }
   



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-12-08 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.86 -> 1.87
---
Log message:

Proper fix for PR1037: http://llvm.org/PR1037 : to determine is a VR is a 
modref, check 1) whether it is
tied to another oeprand, 2) whether is is being tied to by another operand. So
the destination operand of a two-address MI can be correctly identified.

---
Diffs of the changes:  (+4 -2)

 VirtRegMap.cpp |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.86 
llvm/lib/CodeGen/VirtRegMap.cpp:1.87
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.86Thu Dec  7 10:21:19 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Dec  8 02:02:34 2006
@@ -97,7 +97,9 @@
   }
 
   ModRef MRInfo;
-  if (TII.getOperandConstraint(OldMI->getOpcode(), OpNo, TOI::TIED_TO)) {
+  const TargetInstrDescriptor *TID = OldMI->getInstrDescriptor();
+  if (TID->getOperandConstraint(OpNo, TOI::TIED_TO) != -1 ||
+  TII.findTiedToSrcOperand(TID, OpNo) != -1) {
 // Folded a two-address operand.
 MRInfo = isModRef;
   } else if (OldMI->getOperand(OpNo).isDef()) {
@@ -849,7 +851,7 @@
 // If this def is part of a two-address operand, make sure to execute
 // the store from the correct physical register.
 unsigned PhysReg;
-int TiedOp = TII->findTiedToSrcOperand(MI.getOpcode(), i);
+int TiedOp = TII->findTiedToSrcOperand(MI.getInstrDescriptor(), i);
 if (TiedOp != -1)
   PhysReg = MI.getOperand(TiedOp).getReg();
 else {



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-12-07 Thread Reid Spencer


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.85 -> 1.86
---
Log message:

Revision 1.83 causes PR1037: http://llvm.org/PR1037 .
Reverted.


---
Diffs of the changes:  (+1 -2)

 VirtRegMap.cpp |3 +--
 1 files changed, 1 insertion(+), 2 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.85 
llvm/lib/CodeGen/VirtRegMap.cpp:1.86
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.85Wed Dec  6 19:30:31 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Dec  7 10:21:19 2006
@@ -97,8 +97,7 @@
   }
 
   ModRef MRInfo;
-  if (OldMI->getInstrDescriptor()->
-  getOperandConstraint(OpNo, TOI::TIED_TO) != -1) {
+  if (TII.getOperandConstraint(OldMI->getOpcode(), OpNo, TOI::TIED_TO)) {
 // Folded a two-address operand.
 MRInfo = isModRef;
   } else if (OldMI->getOperand(OpNo).isDef()) {



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-12-06 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.82 -> 1.83
---
Log message:

getOperandConstraint returns -1 if the operand does have the specific 
constraint. This bug was causing excessive spills.

---
Diffs of the changes:  (+1 -1)

 VirtRegMap.cpp |2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.82 
llvm/lib/CodeGen/VirtRegMap.cpp:1.83
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.82Wed Dec  6 11:46:31 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Wed Dec  6 18:46:04 2006
@@ -97,7 +97,7 @@
   }
 
   ModRef MRInfo;
-  if (TII.getOperandConstraint(OldMI->getOpcode(), OpNo, TOI::TIED_TO)) {
+  if (TII.getOperandConstraint(OldMI->getOpcode(), OpNo, TOI::TIED_TO) != -1) {
 // Folded a two-address operand.
 MRInfo = isModRef;
   } else if (OldMI->getOperand(OpNo).isDef()) {



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-11-03 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.78 -> 1.79
---
Log message:

Fixed some spiller bugs exposed by the recent two-address code changes. Now
there may be other def(s) apart from the use&def two-address operand. We need
to check if the register reuse for a use&def operand may conflicts with another
def. Provide a mean to recover from the conflict if it is detected when the
defs are processed later.


---
Diffs of the changes:  (+53 -21)

 VirtRegMap.cpp |   74 -
 1 files changed, 53 insertions(+), 21 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.78 
llvm/lib/CodeGen/VirtRegMap.cpp:1.79
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.78Wed Nov  1 17:18:32 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Nov  3 18:21:55 2006
@@ -394,8 +394,15 @@
   class VISIBILITY_HIDDEN ReuseInfo {
 MachineInstr &MI;
 std::vector Reuses;
+bool *PhysRegsClobbered;
   public:
-ReuseInfo(MachineInstr &mi) : MI(mi) {}
+ReuseInfo(MachineInstr &mi, const MRegisterInfo *mri) : MI(mi) {
+  PhysRegsClobbered = new bool[mri->getNumRegs()];
+  std::fill(PhysRegsClobbered, PhysRegsClobbered+mri->getNumRegs(), false);
+}
+~ReuseInfo() {
+  delete[] PhysRegsClobbered;
+}
 
 bool hasReuses() const {
   return !Reuses.empty();
@@ -414,6 +421,14 @@
   Reuses.push_back(ReusedOp(OpNo, StackSlot, PhysRegReused, 
 AssignedPhysReg, VirtReg));
 }
+
+void markClobbered(unsigned PhysReg) {
+  PhysRegsClobbered[PhysReg] = true;
+}
+
+bool isClobbered(unsigned PhysReg) const {
+  return PhysRegsClobbered[PhysReg];
+}
 
 /// GetRegForReload - We are about to emit a reload into PhysReg.  If there
 /// is some other operand that is using the specified register, either pick
@@ -430,11 +445,7 @@
 // register.
 if (Op.PhysRegReused == PhysReg) {
   // Yup, use the reload register that we didn't use before.
-  unsigned NewReg = Op.AssignedPhysReg;
-  
-  // Remove the record for the previous reuse.  We know it can never be
-  // invalidated now.
-  Reuses.erase(Reuses.begin()+ro);
+  unsigned NewReg = Op.AssignedPhysReg;  
   return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores);
 } else {
   // Otherwise, we might also have a problem if a previously reused
@@ -518,8 +529,19 @@
 
 /// ReusedOperands - Keep track of operand reuse in case we need to undo
 /// reuse.
-ReuseInfo ReusedOperands(MI);
-
+ReuseInfo ReusedOperands(MI, MRI);
+
+// Loop over all of the implicit defs, clearing them from our available
+// sets.
+const unsigned *ImpDef = TII->getImplicitDefs(MI.getOpcode());
+if (ImpDef) {
+  for ( ; *ImpDef; ++ImpDef) {
+PhysRegsUsed[*ImpDef] = true;
+ReusedOperands.markClobbered(*ImpDef);
+Spills.ClobberPhysReg(*ImpDef);
+  }
+}
+
 // Process all of the spilled uses and all non spilled reg references.
 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
   MachineOperand &MO = MI.getOperand(i);
@@ -530,6 +552,7 @@
 // Ignore physregs for spilling, but remember that it is used by this
 // function.
 PhysRegsUsed[MO.getReg()] = true;
+ReusedOperands.markClobbered(MO.getReg());
 continue;
   }
   
@@ -541,6 +564,8 @@
 // This virtual register was assigned a physreg!
 unsigned Phys = VRM.getPhys(VirtReg);
 PhysRegsUsed[Phys] = true;
+if (MO.isDef())
+  ReusedOperands.markClobbered(Phys);
 MI.getOperand(i).setReg(Phys);
 continue;
   }
@@ -567,8 +592,10 @@
 MI.getOperand(ti).isReg() && 
 MI.getOperand(ti).getReg() == VirtReg) {
   // Okay, we have a two address operand.  We can reuse this physreg as
-  // long as we are allowed to clobber the value.
-  CanReuse = Spills.canClobberPhysReg(StackSlot);
+  // long as we are allowed to clobber the value and there is an 
earlier
+  // def that has already clobbered the physreg.
+  CanReuse = Spills.canClobberPhysReg(StackSlot) &&
+!ReusedOperands.isClobbered(PhysReg);
 }
 
 if (CanReuse) {
@@ -595,6 +622,9 @@
   // we can get at R0 or its alias.
   ReusedOperands.addReuse(i, StackSlot, PhysReg,
   VRM.getPhys(VirtReg), VirtReg);
+  if (ti != -1)
+// Only mark it clobbered if this is a use&def operand.
+ReusedOperands.markClobbered(PhysReg);
   ++NumReused;
   continue;
 }
@@ -629,6 +659,7 @@
   << VirtReg
   << " instead of reloading into same physreg.\n");
   MI.getOperand(i).setRe

[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-10-12 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.75 -> 1.76
---
Log message:

restore my previous patch, now that the X86 backend bug has been fixed:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20061009/038518.html


---
Diffs of the changes:  (+32 -17)

 VirtRegMap.cpp |   49 -
 1 files changed, 32 insertions(+), 17 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.75 
llvm/lib/CodeGen/VirtRegMap.cpp:1.76
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.75Thu Oct 12 03:00:47 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Oct 12 12:45:38 2006
@@ -706,24 +706,25 @@
   if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) {
 int FrameIdx;
 if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
-  // If this spill slot is available, turn it into a copy (or nothing)
-  // instead of leaving it as a load!
-  unsigned InReg;
-  if (FrameIdx == SS && (InReg = Spills.getSpillSlotPhysReg(SS))) {
-DEBUG(std::cerr << "Promoted Load To Copy: " << MI);
-MachineFunction &MF = *MBB.getParent();
-if (DestReg != InReg) {
-  MRI->copyRegToReg(MBB, &MI, DestReg, InReg,
-MF.getSSARegMap()->getRegClass(VirtReg));
-  // Revisit the copy so we make sure to notice the effects of the
-  // operation on the destreg (either needing to RA it if it's 
-  // virtual or needing to clobber any values if it's physical).
-  NextMII = &MI;
-  --NextMII;  // backtrack to the copy.
+  if (FrameIdx == SS) {
+// If this spill slot is available, turn it into a copy (or 
nothing)
+// instead of leaving it as a load!
+if (unsigned InReg = Spills.getSpillSlotPhysReg(SS)) {
+  DEBUG(std::cerr << "Promoted Load To Copy: " << MI);
+  MachineFunction &MF = *MBB.getParent();
+  if (DestReg != InReg) {
+MRI->copyRegToReg(MBB, &MI, DestReg, InReg,
+  MF.getSSARegMap()->getRegClass(VirtReg));
+// Revisit the copy so we make sure to notice the effects of 
the
+// operation on the destreg (either needing to RA it if it's 
+// virtual or needing to clobber any values if it's physical).
+NextMII = &MI;
+--NextMII;  // backtrack to the copy.
+  }
+  VRM.RemoveFromFoldedVirtMap(&MI);
+  MBB.erase(&MI);
+  goto ProcessNextInst;
 }
-VRM.RemoveFromFoldedVirtMap(&MI);
-MBB.erase(&MI);
-goto ProcessNextInst;
   }
 }
   }
@@ -791,7 +792,21 @@
 VRM.RemoveFromFoldedVirtMap(&MI);
 goto ProcessNextInst;
   }
+  
+  // If it's not a no-op copy, it clobbers the value in the destreg.
   Spills.ClobberPhysReg(VirtReg);
+ 
+  // Check to see if this instruction is a load from a stack slot into
+  // a register.  If so, this provides the stack slot value in the reg.
+  int FrameIdx;
+  if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
+assert(DestReg == VirtReg && "Unknown load situation!");
+
+// Otherwise, if it wasn't available, remember that it is now!
+Spills.addAvailable(FrameIdx, DestReg);
+goto ProcessNextInst;
+  }
+
   continue;
 }
 



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-10-12 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.74 -> 1.75
---
Log message:

Backing out Chris' last commit. It's breaking llvm-gcc bootstrapping.

It's turning:
movl -24(%ebp), %esp
subl $16, %esp
movl -24(%ebp), %ecx
into
movl -24(%ebp), %esp
subl $16, %esp
movl %esp, (%esp) 


---
Diffs of the changes:  (+17 -32)

 VirtRegMap.cpp |   49 +
 1 files changed, 17 insertions(+), 32 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.74 
llvm/lib/CodeGen/VirtRegMap.cpp:1.75
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.74Wed Oct 11 21:34:07 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Oct 12 03:00:47 2006
@@ -706,25 +706,24 @@
   if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) {
 int FrameIdx;
 if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
-  if (FrameIdx == SS) {
-// If this spill slot is available, turn it into a copy (or 
nothing)
-// instead of leaving it as a load!
-if (unsigned InReg = Spills.getSpillSlotPhysReg(SS)) {
-  DEBUG(std::cerr << "Promoted Load To Copy: " << MI);
-  MachineFunction &MF = *MBB.getParent();
-  if (DestReg != InReg) {
-MRI->copyRegToReg(MBB, &MI, DestReg, InReg,
-  MF.getSSARegMap()->getRegClass(VirtReg));
-// Revisit the copy so we make sure to notice the effects of 
the
-// operation on the destreg (either needing to RA it if it's 
-// virtual or needing to clobber any values if it's physical).
-NextMII = &MI;
---NextMII;  // backtrack to the copy.
-  }
-  VRM.RemoveFromFoldedVirtMap(&MI);
-  MBB.erase(&MI);
-  goto ProcessNextInst;
+  // If this spill slot is available, turn it into a copy (or nothing)
+  // instead of leaving it as a load!
+  unsigned InReg;
+  if (FrameIdx == SS && (InReg = Spills.getSpillSlotPhysReg(SS))) {
+DEBUG(std::cerr << "Promoted Load To Copy: " << MI);
+MachineFunction &MF = *MBB.getParent();
+if (DestReg != InReg) {
+  MRI->copyRegToReg(MBB, &MI, DestReg, InReg,
+MF.getSSARegMap()->getRegClass(VirtReg));
+  // Revisit the copy so we make sure to notice the effects of the
+  // operation on the destreg (either needing to RA it if it's 
+  // virtual or needing to clobber any values if it's physical).
+  NextMII = &MI;
+  --NextMII;  // backtrack to the copy.
 }
+VRM.RemoveFromFoldedVirtMap(&MI);
+MBB.erase(&MI);
+goto ProcessNextInst;
   }
 }
   }
@@ -792,21 +791,7 @@
 VRM.RemoveFromFoldedVirtMap(&MI);
 goto ProcessNextInst;
   }
-  
-  // If it's not a no-op copy, it clobbers the value in the destreg.
   Spills.ClobberPhysReg(VirtReg);
- 
-  // Check to see if this instruction is a load from a stack slot into
-  // a register.  If so, this provides the stack slot value in the reg.
-  int FrameIdx;
-  if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
-assert(DestReg == VirtReg && "Unknown load situation!");
-
-// Otherwise, if it wasn't available, remember that it is now!
-Spills.addAvailable(FrameIdx, DestReg);
-goto ProcessNextInst;
-  }
-
   continue;
 }
 



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-10-11 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.73 -> 1.74
---
Log message:

If we see a load from a stack slot into a physreg, consider it as providing
the stack slot.  This fixes PR943: http://llvm.org/PR943 .


---
Diffs of the changes:  (+32 -17)

 VirtRegMap.cpp |   49 -
 1 files changed, 32 insertions(+), 17 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.73 
llvm/lib/CodeGen/VirtRegMap.cpp:1.74
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.73Mon Sep  4 21:12:02 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Wed Oct 11 21:34:07 2006
@@ -706,24 +706,25 @@
   if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) {
 int FrameIdx;
 if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
-  // If this spill slot is available, turn it into a copy (or nothing)
-  // instead of leaving it as a load!
-  unsigned InReg;
-  if (FrameIdx == SS && (InReg = Spills.getSpillSlotPhysReg(SS))) {
-DEBUG(std::cerr << "Promoted Load To Copy: " << MI);
-MachineFunction &MF = *MBB.getParent();
-if (DestReg != InReg) {
-  MRI->copyRegToReg(MBB, &MI, DestReg, InReg,
-MF.getSSARegMap()->getRegClass(VirtReg));
-  // Revisit the copy so we make sure to notice the effects of the
-  // operation on the destreg (either needing to RA it if it's 
-  // virtual or needing to clobber any values if it's physical).
-  NextMII = &MI;
-  --NextMII;  // backtrack to the copy.
+  if (FrameIdx == SS) {
+// If this spill slot is available, turn it into a copy (or 
nothing)
+// instead of leaving it as a load!
+if (unsigned InReg = Spills.getSpillSlotPhysReg(SS)) {
+  DEBUG(std::cerr << "Promoted Load To Copy: " << MI);
+  MachineFunction &MF = *MBB.getParent();
+  if (DestReg != InReg) {
+MRI->copyRegToReg(MBB, &MI, DestReg, InReg,
+  MF.getSSARegMap()->getRegClass(VirtReg));
+// Revisit the copy so we make sure to notice the effects of 
the
+// operation on the destreg (either needing to RA it if it's 
+// virtual or needing to clobber any values if it's physical).
+NextMII = &MI;
+--NextMII;  // backtrack to the copy.
+  }
+  VRM.RemoveFromFoldedVirtMap(&MI);
+  MBB.erase(&MI);
+  goto ProcessNextInst;
 }
-VRM.RemoveFromFoldedVirtMap(&MI);
-MBB.erase(&MI);
-goto ProcessNextInst;
   }
 }
   }
@@ -791,7 +792,21 @@
 VRM.RemoveFromFoldedVirtMap(&MI);
 goto ProcessNextInst;
   }
+  
+  // If it's not a no-op copy, it clobbers the value in the destreg.
   Spills.ClobberPhysReg(VirtReg);
+ 
+  // Check to see if this instruction is a load from a stack slot into
+  // a register.  If so, this provides the stack slot value in the reg.
+  int FrameIdx;
+  if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
+assert(DestReg == VirtReg && "Unknown load situation!");
+
+// Otherwise, if it wasn't available, remember that it is now!
+Spills.addAvailable(FrameIdx, DestReg);
+goto ProcessNextInst;
+  }
+
   continue;
 }
 



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-08-21 Thread Bill Wendling


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.69 -> 1.70
---
Log message:

Added a check so that if we have two machine instructions in this form

MOV R0, R1
MOV R1, R0

the second machine instruction is removed. Added a regression test.


---
Diffs of the changes:  (+30 -10)

 VirtRegMap.cpp |   40 ++--
 1 files changed, 30 insertions(+), 10 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.69 
llvm/lib/CodeGen/VirtRegMap.cpp:1.70
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.69Fri Jul 21 16:15:20 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Mon Aug 21 02:33:33 2006
@@ -521,6 +521,7 @@
 // Process all of the spilled uses and all non spilled reg references.
 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
   MachineOperand &MO = MI.getOperand(i);
+
   if (!MO.isRegister() || MO.getReg() == 0)
 continue;   // Ignore non-register operands.
   
@@ -790,16 +791,37 @@
   }
 
   if (!OpTakenCareOf) {
-// Check to see if this is a noop copy.  If so, eliminate the
-// instruction before considering the dest reg to be changed.
 unsigned Src, Dst;
-if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
-  ++NumDCE;
-  DEBUG(std::cerr << "Removing now-noop copy: " << MI);
-  MBB.erase(&MI);
-  VRM.RemoveFromFoldedVirtMap(&MI);
-  goto ProcessNextInst;
+if (TII->isMoveInstr(MI, Src, Dst)) {
+  if (Src == Dst) {
+// Check to see if this is a noop copy.  If so, eliminate
+// the instruction before considering the dest reg to be
+// changed.
+++NumDCE;
+DEBUG(std::cerr << "Removing now-noop copy: " << MI);
+MBB.erase(&MI);
+VRM.RemoveFromFoldedVirtMap(&MI);
+goto ProcessNextInst;
+  } else if (MII != MBB.begin()) {
+// Check to see if this is a sequence of the form:
+//mov R0, R1
+//mov R1, R0
+// Eliminate the second move if so.
+MachineBasicBlock::iterator PrevMII = MII; --PrevMII;
+MachineInstr& PrevMI = *PrevMII;
+unsigned PrevSrc, PrevDst;
+
+if (TII->isMoveInstr(PrevMI, PrevSrc, PrevDst))
+  if (PrevSrc == Dst && PrevDst == Src) {
+++NumDCE;
+DEBUG(std::cerr << "Removing now-noop copy: " << MI);
+MBB.erase(&MI);
+VRM.RemoveFromFoldedVirtMap(&MI);
+goto ProcessNextInst;
+  }
+  }
 }
+
 Spills.ClobberPhysReg(VirtReg);
 continue;
   }
@@ -861,8 +883,6 @@
   }
 }
 
-
-
 llvm::Spiller* llvm::createSpiller() {
   switch (SpillerOpt) {
   default: assert(0 && "Unreachable!");



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp VirtRegMap.h

2006-05-01 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.64 -> 1.65
VirtRegMap.h updated: 1.20 -> 1.21
---
Log message:

Fix a latent bug that my spiller patch last week exposed: we were leaving
instructions in the virtregfolded map that were deleted.  Because they 
were deleted, newly allocated instructions could end up at the same address,
magically finding themselves in the map.  The solution is to remove entries
from the map when we delete the instructions.


---
Diffs of the changes:  (+7 -4)

 VirtRegMap.cpp |4 
 VirtRegMap.h   |7 +++
 2 files changed, 7 insertions(+), 4 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.64 
llvm/lib/CodeGen/VirtRegMap.cpp:1.65
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.64Mon May  1 16:17:10 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Mon May  1 17:03:24 2006
@@ -730,6 +730,7 @@
   assert(VirtRegMap::isMod && "Can't be modref!");
   DEBUG(std::cerr << "Removed dead store:\t" << *MDSI->second);
   MBB.erase(MDSI->second);
+  VRM.RemoveFromFoldedVirtMap(MDSI->second);
   MaybeDeadStores.erase(MDSI);
   ++NumDSE;
 }
@@ -791,6 +792,7 @@
   ++NumDCE;
   DEBUG(std::cerr << "Removing now-noop copy: " << MI);
   MBB.erase(&MI);
+  VRM.RemoveFromFoldedVirtMap(&MI);
   goto ProcessNextInst;
 }
 Spills.ClobberPhysReg(VirtReg);
@@ -825,6 +827,7 @@
 ++NumDCE;
 DEBUG(std::cerr << "Removing now-noop copy: " << MI);
 MBB.erase(&MI);
+VRM.RemoveFromFoldedVirtMap(&MI);
 goto ProcessNextInst;
   }
 }
@@ -835,6 +838,7 @@
   DEBUG(std::cerr << "Removed dead store:\t" << *LastStore);
   ++NumDSE;
   MBB.erase(LastStore);
+  VRM.RemoveFromFoldedVirtMap(LastStore);
 }
 LastStore = next(MII);
 


Index: llvm/lib/CodeGen/VirtRegMap.h
diff -u llvm/lib/CodeGen/VirtRegMap.h:1.20 llvm/lib/CodeGen/VirtRegMap.h:1.21
--- llvm/lib/CodeGen/VirtRegMap.h:1.20  Mon May  1 16:16:03 2006
+++ llvm/lib/CodeGen/VirtRegMap.h   Mon May  1 17:03:24 2006
@@ -137,11 +137,10 @@
   return MI2VirtMap.equal_range(MI);
 }
 
-/// RemoveFromFoldedVirtMap - Given a machine instruction in the folded
-/// instruction map, remove the entry in the folded instruction map.
+/// RemoveFromFoldedVirtMap - If the specified machine instruction is in
+/// the folded instruction map, remove its entry from the map.
 void RemoveFromFoldedVirtMap(MachineInstr *MI) {
-  bool ErasedAny = MI2VirtMap.erase(MI);
-  assert(ErasedAny && "Machine instr not in folded vreg map!");
+  MI2VirtMap.erase(MI);
 }
 
 void print(std::ostream &OS) const;



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-05-01 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.63 -> 1.64
---
Log message:

When promoting a load to a reg-reg copy, where the load was a previous 
instruction folded with spill code, make sure the remove the load from
the virt reg folded map.


---
Diffs of the changes:  (+1 -0)

 VirtRegMap.cpp |1 +
 1 files changed, 1 insertion(+)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.63 
llvm/lib/CodeGen/VirtRegMap.cpp:1.64
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.63Mon May  1 16:16:03 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Mon May  1 16:17:10 2006
@@ -712,6 +712,7 @@
   NextMII = &MI;
   --NextMII;  // backtrack to the copy.
 }
+VRM.RemoveFromFoldedVirtMap(&MI);
 MBB.erase(&MI);
 goto ProcessNextInst;
   }



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-05-01 Thread Evan Cheng


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.61 -> 1.62
---
Log message:

Remove temp. option -spiller-check-liveout, it didn't cause any failure nor 
performance regressions.

---
Diffs of the changes:  (+1 -5)

 VirtRegMap.cpp |6 +-
 1 files changed, 1 insertion(+), 5 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.61 
llvm/lib/CodeGen/VirtRegMap.cpp:1.62
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.61Sun Apr 30 03:41:47 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Mon May  1 03:54:57 2006
@@ -50,10 +50,6 @@
 clEnumVal(local,  "  local spiller"),
 clEnumValEnd),
  cl::init(local));
-
-  // TEMPORARY option to test a fix.
-  cl::opt
-  SpillerCheckLiveOut("spiller-check-liveout", cl::Hidden);
 }
 
 
//===--===//
@@ -735,7 +731,7 @@
   // If we get here, the store is dead, nuke it now.
   assert(!(MR & VirtRegMap::isRef) && "Can't be modref!");
   // Don't nuke it if the value is needed in another block.
-  if (!SpillerCheckLiveOut || !(MR & VirtRegMap::isLiveOut)) {
+  if (!(MR & VirtRegMap::isLiveOut)) {
 DEBUG(std::cerr << " Killed store:\t" << *MDSI->second);
 MBB.erase(MDSI->second);
 MaybeDeadStores.erase(MDSI);



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-04-27 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.59 -> 1.60
---
Log message:

Mapping of physregs can make it so that the designated and input physregs are
the same.  In this case, don't emit a noop copy.


---
Diffs of the changes:  (+13 -0)

 VirtRegMap.cpp |   13 +
 1 files changed, 13 insertions(+)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.59 
llvm/lib/CodeGen/VirtRegMap.cpp:1.60
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.59Thu Apr 27 20:46:50 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Apr 27 23:43:18 2006
@@ -611,6 +611,19 @@
   DesignatedReg = ReusedOperands.GetRegForReload(DesignatedReg, &MI, 
   Spills, MaybeDeadStores);
 
+// If the mapped designated register is actually the physreg we have
+// incoming, we don't need to inserted a dead copy.
+if (DesignatedReg == PhysReg) {
+  // If this stack slot value is already available, reuse it!
+  DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg "
+  << MRI->getName(PhysReg) << " for vreg"
+  << VirtReg
+  << " instead of reloading into same physreg.\n");
+  MI.SetMachineOperandReg(i, PhysReg);
+  ++NumReused;
+  continue;
+}
+
 const TargetRegisterClass* RC =
   MBB.getParent()->getSSARegMap()->getRegClass(VirtReg);
 



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-04-27 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.58 -> 1.59
---
Log message:

When we have a two-address instruction where the input cannot be clobbered
and is already available, instead of falling back to emitting a load, fall
back to emitting a reg-reg copy.  This generates significantly better code
for some SSE testcases, as SSE has lots of two-address instructions and
none of them are read/modify/write.  As one example, this change does:

pshufd %XMM5, XMMWORD PTR [%ESP + 84], 255
xorps %XMM2, %XMM5
cmpltps %XMM1, %XMM0
-   movaps XMMWORD PTR [%ESP + 52], %XMM0
-   movapd %XMM6, XMMWORD PTR [%ESP + 52]
+   movaps %XMM6, %XMM0
cmpltps %XMM6, XMMWORD PTR [%ESP + 68]
movapd XMMWORD PTR [%ESP + 52], %XMM6
movaps %XMM6, %XMM0
cmpltps %XMM6, XMMWORD PTR [%ESP + 36]
cmpltps %XMM3, %XMM0
-   movaps XMMWORD PTR [%ESP + 20], %XMM0
-   movapd %XMM7, XMMWORD PTR [%ESP + 20]
+   movaps %XMM7, %XMM0
cmpltps %XMM7, XMMWORD PTR [%ESP + 4]
movapd XMMWORD PTR [%ESP + 20], %XMM7
cmpltps %XMM4, %XMM0

... which is far better than a store followed by a load!



---
Diffs of the changes:  (+63 -25)

 VirtRegMap.cpp |   88 -
 1 files changed, 63 insertions(+), 25 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.58 
llvm/lib/CodeGen/VirtRegMap.cpp:1.59
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.58Fri Feb 24 20:17:31 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Apr 27 20:46:50 2006
@@ -558,33 +558,71 @@
   unsigned PhysReg;
 
   // Check to see if this stack slot is available.
-  if ((PhysReg = Spills.getSpillSlotPhysReg(StackSlot)) &&
-  // Don't reuse it for a def&use operand if we aren't allowed to 
change
-  // the physreg!
-  (!MO.isDef() || Spills.canClobberPhysReg(StackSlot))) {
-// If this stack slot value is already available, reuse it!
-DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg "
-<< MRI->getName(PhysReg) << " for vreg"
-<< VirtReg <<" instead of reloading into physreg "
-<< MRI->getName(VRM.getPhys(VirtReg)) << "\n");
-MI.SetMachineOperandReg(i, PhysReg);
+  if ((PhysReg = Spills.getSpillSlotPhysReg(StackSlot))) {
 
-// The only technical detail we have is that we don't know that
-// PhysReg won't be clobbered by a reloaded stack slot that occurs
-// later in the instruction.  In particular, consider 'op V1, V2'.
-// If V1 is available in physreg R0, we would choose to reuse it
-// here, instead of reloading it into the register the allocator
-// indicated (say R1).  However, V2 might have to be reloaded
-// later, and it might indicate that it needs to live in R0.  When
-// this occurs, we need to have information available that
-// indicates it is safe to use R1 for the reload instead of R0.
+// Don't reuse it for a def&use operand if we aren't allowed to change
+// the physreg!
+if (!MO.isDef() || Spills.canClobberPhysReg(StackSlot)) {
+  // If this stack slot value is already available, reuse it!
+  DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg "
+  << MRI->getName(PhysReg) << " for vreg"
+  << VirtReg <<" instead of reloading into physreg "
+  << MRI->getName(VRM.getPhys(VirtReg)) << "\n");
+  MI.SetMachineOperandReg(i, PhysReg);
+
+  // The only technical detail we have is that we don't know that
+  // PhysReg won't be clobbered by a reloaded stack slot that occurs
+  // later in the instruction.  In particular, consider 'op V1, V2'.
+  // If V1 is available in physreg R0, we would choose to reuse it
+  // here, instead of reloading it into the register the allocator
+  // indicated (say R1).  However, V2 might have to be reloaded
+  // later, and it might indicate that it needs to live in R0.  When
+  // this occurs, we need to have information available that
+  // indicates it is safe to use R1 for the reload instead of R0.
+  //
+  // To further complicate matters, we might conflict with an alias,
+  // or R0 and R1 might not be compatible with each other.  In this
+  // case, we actually insert a reload for V1 in R1, ensuring that
+  // we can get at R0 or its alias.
+  ReusedOperands.addReuse(i, StackSlot, PhysReg,
+  VRM.getPhys(VirtReg), VirtReg);
+  ++NumReused;
+  continue;
+}
+
+// Otherwise we have a situation where we have a two-address 
instruction
+// whose mod/ref operand needs to be reloaded.  This re

[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-24 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.57 -> 1.58
---
Log message:

Fix a bug that Evan exposed with some changes he's making, and that was
exposed with a fastcc problem (breaking pcompress2 on x86 with 
-enable-x86-fastcc).

When reloading a reused reg, make sure to invalidate the reloaded reg, and
check to see if there are any other pending uses of the same register.


---
Diffs of the changes:  (+23 -9)

 VirtRegMap.cpp |   32 +++-
 1 files changed, 23 insertions(+), 9 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.57 
llvm/lib/CodeGen/VirtRegMap.cpp:1.58
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.57Fri Feb 24 20:03:40 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 24 20:17:31 2006
@@ -437,25 +437,39 @@
 // to undo a previous reuse.
 MachineBasicBlock *MBB = MI->getParent();
 const TargetRegisterClass *AliasRC =
-MBB->getParent()->getSSARegMap()->getRegClass(Op.VirtReg);
-MRI->loadRegFromStackSlot(*MBB, MI, Op.AssignedPhysReg,
-  Op.StackSlot, AliasRC);
-Spills.ClobberPhysReg(Op.AssignedPhysReg);
-Spills.ClobberPhysReg(Op.PhysRegReused);
+  MBB->getParent()->getSSARegMap()->getRegClass(Op.VirtReg);
+
+// Copy Op out of the vector and remove it, we're going to insert 
an
+// explicit load for it.
+ReusedOp NewOp = Op;
+Reuses.erase(Reuses.begin()+ro);
+
+// Ok, we're going to try to reload the assigned physreg into the
+// slot that we were supposed to in the first place.  However, that
+// register could hold a reuse.  Check to see if it conflicts or
+// would prefer us to use a different register.
+unsigned NewPhysReg = GetRegForReload(NewOp.AssignedPhysReg,
+  MI, Spills, MaybeDeadStores);
+
+MRI->loadRegFromStackSlot(*MBB, MI, NewPhysReg,
+  NewOp.StackSlot, AliasRC);
+Spills.ClobberPhysReg(NewPhysReg);
+Spills.ClobberPhysReg(NewOp.PhysRegReused);
 
 // Any stores to this stack slot are not dead anymore.
-MaybeDeadStores.erase(Op.StackSlot);
+MaybeDeadStores.erase(NewOp.StackSlot);
 
-MI->SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg);
+MI->SetMachineOperandReg(NewOp.Operand, NewPhysReg);
 
-Spills.addAvailable(Op.StackSlot, Op.AssignedPhysReg);
+Spills.addAvailable(NewOp.StackSlot, NewPhysReg);
 ++NumLoads;
 DEBUG(MachineBasicBlock::iterator MII = MI;
   std::cerr << '\t' << *prior(MII));
 
 DEBUG(std::cerr << "Reuse undone!\n");
-Reuses.erase(Reuses.begin()+ro);
 --NumReused;
+
+// Finally, PhysReg is now available, go ahead and use it.
 return PhysReg;
   }
 }



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-24 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.56 -> 1.57
---
Log message:

Remove debugging printout :)

Add a minor compile time win, no codegen change.


---
Diffs of the changes:  (+6 -5)

 VirtRegMap.cpp |   11 ++-
 1 files changed, 6 insertions(+), 5 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.56 
llvm/lib/CodeGen/VirtRegMap.cpp:1.57
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.56Fri Feb 24 19:51:33 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 24 20:03:40 2006
@@ -419,8 +419,12 @@
 // register.
 if (Op.PhysRegReused == PhysReg) {
   // Yup, use the reload register that we didn't use before.
-  return GetRegForReload(Op.AssignedPhysReg, MI, 
- Spills, MaybeDeadStores);
+  unsigned NewReg = Op.AssignedPhysReg;
+  
+  // Remove the record for the previous reuse.  We know it can never be
+  // invalidated now.
+  Reuses.erase(Reuses.begin()+ro);
+  return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores);
 } else {
   // Otherwise, we might also have a problem if a previously reused
   // value aliases the new register.  If so, codegen the previous 
reload
@@ -487,9 +491,6 @@
 
   bool *PhysRegsUsed = MBB.getParent()->getUsedPhysregs();
 
-  if (MBB.getBasicBlock()->getName() == "endif.3.i")
-std::cerr << "HERE\n";
-  
   for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
MII != E; ) {
 MachineInstr &MI = *MII;



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-24 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.55 -> 1.56
---
Log message:

Refactor some code from being inline to being out in a new class with methods.
This gets rid of two gotos, which is always nice, and also adds some comments.

No functionality change, this is just a refactor.


---
Diffs of the changes:  (+97 -42)

 VirtRegMap.cpp |  139 +++--
 1 files changed, 97 insertions(+), 42 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.55 
llvm/lib/CodeGen/VirtRegMap.cpp:1.56
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.55Fri Feb  3 21:27:39 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 24 19:51:33 2006
@@ -269,6 +269,8 @@
   return I->second >> 1;  // Remove the CanClobber bit.
 return 0;
   }
+  
+  const MRegisterInfo *getRegInfo() const { return MRI; }
 
   /// addAvailable - Mark that the specified stack slot is available in the
   /// specified physreg.  If CanClobber is true, the physreg can be modified at
@@ -375,6 +377,88 @@
   : Operand(o), StackSlot(ss), PhysRegReused(prr), AssignedPhysReg(apr),
   VirtReg(vreg) {}
   };
+  
+  /// ReuseInfo - This maintains a collection of ReuseOp's for each operand 
that
+  /// is reused instead of reloaded.
+  class ReuseInfo {
+MachineInstr &MI;
+std::vector Reuses;
+  public:
+ReuseInfo(MachineInstr &mi) : MI(mi) {}
+
+bool hasReuses() const {
+  return !Reuses.empty();
+}
+
+/// addReuse - If we choose to reuse a virtual register that is already
+/// available instead of reloading it, remember that we did so.
+void addReuse(unsigned OpNo, unsigned StackSlot,
+  unsigned PhysRegReused, unsigned AssignedPhysReg,
+  unsigned VirtReg) {
+  // If the reload is to the assigned register anyway, no undo will be
+  // required.
+  if (PhysRegReused == AssignedPhysReg) return;
+  
+  // Otherwise, remember this.
+  Reuses.push_back(ReusedOp(OpNo, StackSlot, PhysRegReused, 
+AssignedPhysReg, VirtReg));
+}
+
+/// GetRegForReload - We are about to emit a reload into PhysReg.  If there
+/// is some other operand that is using the specified register, either pick
+/// a new register to use, or evict the previous reload and use this reg. 
+unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI,
+ AvailableSpills &Spills,
+ std::map &MaybeDeadStores) {
+  if (Reuses.empty()) return PhysReg;  // This is most often empty.
+
+  for (unsigned ro = 0, e = Reuses.size(); ro != e; ++ro) {
+ReusedOp &Op = Reuses[ro];
+// If we find some other reuse that was supposed to use this register
+// exactly for its reload, we can change this reload to use ITS reload
+// register.
+if (Op.PhysRegReused == PhysReg) {
+  // Yup, use the reload register that we didn't use before.
+  return GetRegForReload(Op.AssignedPhysReg, MI, 
+ Spills, MaybeDeadStores);
+} else {
+  // Otherwise, we might also have a problem if a previously reused
+  // value aliases the new register.  If so, codegen the previous 
reload
+  // and use this one.  
+  unsigned PRRU = Op.PhysRegReused;
+  const MRegisterInfo *MRI = Spills.getRegInfo();
+  if (MRI->areAliases(PRRU, PhysReg)) {
+// Okay, we found out that an alias of a reused register
+// was used.  This isn't good because it means we have
+// to undo a previous reuse.
+MachineBasicBlock *MBB = MI->getParent();
+const TargetRegisterClass *AliasRC =
+MBB->getParent()->getSSARegMap()->getRegClass(Op.VirtReg);
+MRI->loadRegFromStackSlot(*MBB, MI, Op.AssignedPhysReg,
+  Op.StackSlot, AliasRC);
+Spills.ClobberPhysReg(Op.AssignedPhysReg);
+Spills.ClobberPhysReg(Op.PhysRegReused);
+
+// Any stores to this stack slot are not dead anymore.
+MaybeDeadStores.erase(Op.StackSlot);
+
+MI->SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg);
+
+Spills.addAvailable(Op.StackSlot, Op.AssignedPhysReg);
+++NumLoads;
+DEBUG(MachineBasicBlock::iterator MII = MI;
+  std::cerr << '\t' << *prior(MII));
+
+DEBUG(std::cerr << "Reuse undone!\n");
+Reuses.erase(Reuses.begin()+ro);
+--NumReused;
+return PhysReg;
+  }
+}
+  }
+  return PhysReg;
+}
+  };
 }
 
 
@@ -388,8 +472,6 @@
   // that we can choose to reuse the physregs instead of emitting reloads.
   AvailableSpills Spills(MRI, TII);
   
-  std::vector ReusedOperands;
-
  

[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-03 Thread Jeff Cohen


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.54 -> 1.55
---
Log message:

Fix VC++ warning.

---
Diffs of the changes:  (+1 -1)

 VirtRegMap.cpp |2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.54 
llvm/lib/CodeGen/VirtRegMap.cpp:1.55
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.54Fri Feb  3 17:50:46 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb  3 21:27:39 2006
@@ -279,7 +279,7 @@
 ModifyStackSlot(Slot);
 
 PhysRegsAvailable.insert(std::make_pair(Reg, Slot));
-SpillSlotsAvailable[Slot] = (Reg << 1) | CanClobber;
+SpillSlotsAvailable[Slot] = (Reg << 1) | (unsigned)CanClobber;
   
 DEBUG(std::cerr << "Remembering SS#" << Slot << " in physreg "
 << MRI->getName(Reg) << "\n");



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-03 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.53 -> 1.54
---
Log message:

Handle another case exposed on X86.


---
Diffs of the changes:  (+4 -0)

 VirtRegMap.cpp |4 
 1 files changed, 4 insertions(+)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.53 
llvm/lib/CodeGen/VirtRegMap.cpp:1.54
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.53Fri Feb  3 17:28:46 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb  3 17:50:46 2006
@@ -274,6 +274,10 @@
   /// specified physreg.  If CanClobber is true, the physreg can be modified at
   /// any time without changing the semantics of the program.
   void addAvailable(int Slot, unsigned Reg, bool CanClobber = true) {
+// If this stack slot is thought to be available in some other physreg, 
+// remove its record.
+ModifyStackSlot(Slot);
+
 PhysRegsAvailable.insert(std::make_pair(Reg, Slot));
 SpillSlotsAvailable[Slot] = (Reg << 1) | CanClobber;
   



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-03 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.52 -> 1.53
---
Log message:

Fix a nasty problem on two-address machines in the following situation:

store EAX -> [ss#0]
[ss#0] += 1
...
use(EAX)

In this case, it is not valid to rewrite this as:


store EAX -> [ss#0]
EAX += 1
store EAX -> [ss#0]  ;;; this would also delete the store above
...
use(EAX)

... because EAX is not a dead at that point.  Keep track of which registers
we are allowed to clobber, and which ones we aren't, and don't clobber the
ones we're not supposed to.  :)

This should resolve the issues on X86 last night.



---
Diffs of the changes:  (+27 -9)

 VirtRegMap.cpp |   36 +++-
 1 files changed, 27 insertions(+), 9 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.52 
llvm/lib/CodeGen/VirtRegMap.cpp:1.53
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.52Fri Feb  3 17:13:58 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb  3 17:28:46 2006
@@ -233,6 +233,14 @@
 
 /// AvailableSpills - As the local spiller is scanning and rewriting an MBB 
from
 /// top down, keep track of which spills slots are available in each register.
+///
+/// Note that not all physregs are created equal here.  In particular, some
+/// physregs are reloads that we are allowed to clobber or ignore at any time.
+/// Other physregs are values that the register allocated program is using that
+/// we cannot CHANGE, but we can read if we like.  We keep track of this on a 
+/// per-stack-slot basis as the low bit in the value of the SpillSlotsAvailable
+/// entries.  The predicate 'canClobberPhysReg()' checks this bit and
+/// addAvailable sets it if.
 class AvailableSpills {
   const MRegisterInfo *MRI;
   const TargetInstrInfo *TII;
@@ -258,20 +266,28 @@
   unsigned getSpillSlotPhysReg(int Slot) const {
 std::map::const_iterator I = SpillSlotsAvailable.find(Slot);
 if (I != SpillSlotsAvailable.end())
-  return I->second;
+  return I->second >> 1;  // Remove the CanClobber bit.
 return 0;
   }
 
   /// addAvailable - Mark that the specified stack slot is available in the
-  /// specified physreg.
-  void addAvailable(int Slot, unsigned Reg) {
+  /// specified physreg.  If CanClobber is true, the physreg can be modified at
+  /// any time without changing the semantics of the program.
+  void addAvailable(int Slot, unsigned Reg, bool CanClobber = true) {
 PhysRegsAvailable.insert(std::make_pair(Reg, Slot));
-SpillSlotsAvailable[Slot] = Reg;
+SpillSlotsAvailable[Slot] = (Reg << 1) | CanClobber;
   
 DEBUG(std::cerr << "Remembering SS#" << Slot << " in physreg "
 << MRI->getName(Reg) << "\n");
   }
   
+  /// canClobberPhysReg - Return true if the spiller is allowed to change the 
+  /// value of the specified stackslot register if it desires.  The specified
+  /// stack slot must be available in a physreg for this query to make sense.
+  bool canClobberPhysReg(int Slot) const {
+assert(SpillSlotsAvailable.count(Slot) && "Slot not available!");
+return SpillSlotsAvailable.find(Slot)->second & 1;
+  }
   
   /// ClobberPhysReg - This is called when the specified physreg changes
   /// value.  We use this to invalidate any info about stuff we thing lives in
@@ -292,7 +308,7 @@
   while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
 int Slot = I->second;
 PhysRegsAvailable.erase(I++);
-assert(SpillSlotsAvailable[Slot] == PhysReg &&
+assert((SpillSlotsAvailable[Slot] >> 1) == PhysReg &&
"Bidirectional map mismatch!");
 SpillSlotsAvailable.erase(Slot);
 DEBUG(std::cerr << "PhysReg " << MRI->getName(PhysReg)
@@ -315,7 +331,7 @@
 void AvailableSpills::ModifyStackSlot(int Slot) {
   std::map::iterator It = SpillSlotsAvailable.find(Slot);
   if (It == SpillSlotsAvailable.end()) return;
-  unsigned Reg = It->second;
+  unsigned Reg = It->second >> 1;
   SpillSlotsAvailable.erase(It);
   
   // This register may hold the value of multiple stack slots, only remove this
@@ -435,7 +451,10 @@
   unsigned PhysReg;
 
   // Check to see if this stack slot is available.
-  if ((PhysReg = Spills.getSpillSlotPhysReg(StackSlot))) {
+  if ((PhysReg = Spills.getSpillSlotPhysReg(StackSlot)) &&
+  // Don't reuse it for a def&use operand if we aren't allowed to 
change
+  // the physreg!
+  (!MO.isDef() || Spills.canClobberPhysReg(StackSlot))) {
 // If this stack slot value is already available, reuse it!
 DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg "
 << MRI->getName(PhysReg) << " for vreg"
@@ -613,7 +632,7 @@
 // If the stack slot value was previously available in some other
 // register, change it now.  Otherwise, make the register 
available,
 // in PhysReg.
-Spills.addAvailable(StackSlot, SrcReg);
+Spills.addAvailable(StackSlot, Src

[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-03 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.51 -> 1.52
---
Log message:

significantly simplify the VirtRegMap code by pulling the SpillSlotsAvailable
and PhysRegsAvailable maps out into a new AvailableSpills struct.  No
functionality change.

This paves the way for a bugfix, coming up next.


---
Diffs of the changes:  (+97 -69)

 VirtRegMap.cpp |  166 +
 1 files changed, 97 insertions(+), 69 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.51 
llvm/lib/CodeGen/VirtRegMap.cpp:1.52
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.51Thu Feb  2 21:48:54 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb  3 17:13:58 2006
@@ -231,38 +231,92 @@
   };
 }
 
-void LocalSpiller::ClobberPhysRegOnly(unsigned PhysReg,
-  std::map &SpillSlots,
-  std::multimap &PhysRegsAvailable) 
{
-  std::multimap::iterator I = 
PhysRegsAvailable.lower_bound(PhysReg);
+/// AvailableSpills - As the local spiller is scanning and rewriting an MBB 
from
+/// top down, keep track of which spills slots are available in each register.
+class AvailableSpills {
+  const MRegisterInfo *MRI;
+  const TargetInstrInfo *TII;
+
+  // 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.
+  std::map SpillSlotsAvailable;
+
+  // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating
+  // which stack slot values are currently held by a physreg.  This is used to
+  // invalidate entries in SpillSlotsAvailable when a physreg is modified.
+  std::multimap PhysRegsAvailable;
+  
+  void ClobberPhysRegOnly(unsigned PhysReg);
+public:
+  AvailableSpills(const MRegisterInfo *mri, const TargetInstrInfo *tii)
+: MRI(mri), TII(tii) {
+  }
+  
+  /// getSpillSlotPhysReg - If the specified stack slot is available in a 
+  /// physical register, return that PhysReg, otherwise return 0.
+  unsigned getSpillSlotPhysReg(int Slot) const {
+std::map::const_iterator I = SpillSlotsAvailable.find(Slot);
+if (I != SpillSlotsAvailable.end())
+  return I->second;
+return 0;
+  }
+
+  /// addAvailable - Mark that the specified stack slot is available in the
+  /// specified physreg.
+  void addAvailable(int Slot, unsigned Reg) {
+PhysRegsAvailable.insert(std::make_pair(Reg, Slot));
+SpillSlotsAvailable[Slot] = Reg;
+  
+DEBUG(std::cerr << "Remembering SS#" << Slot << " in physreg "
+<< MRI->getName(Reg) << "\n");
+  }
+  
+  
+  /// ClobberPhysReg - This is called when the specified physreg changes
+  /// value.  We use this to invalidate any info about stuff we thing lives in
+  /// it and any of its aliases.
+  void ClobberPhysReg(unsigned PhysReg);
+
+  /// ModifyStackSlot - This method is called when the value in a stack slot
+  /// changes.  This removes information about which register the previous 
value
+  /// for this slot lives in (as the previous value is dead now).
+  void ModifyStackSlot(int Slot);
+};
+
+/// ClobberPhysRegOnly - This is called when the specified physreg changes
+/// value.  We use this to invalidate any info about stuff we thing lives in 
it.
+void AvailableSpills::ClobberPhysRegOnly(unsigned PhysReg) {
+  std::multimap::iterator I =
+PhysRegsAvailable.lower_bound(PhysReg);
   while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
 int Slot = I->second;
 PhysRegsAvailable.erase(I++);
-assert(SpillSlots[Slot] == PhysReg && "Bidirectional map mismatch!");
-SpillSlots.erase(Slot);
+assert(SpillSlotsAvailable[Slot] == PhysReg &&
+   "Bidirectional map mismatch!");
+SpillSlotsAvailable.erase(Slot);
 DEBUG(std::cerr << "PhysReg " << MRI->getName(PhysReg)
 << " clobbered, invalidating SS#" << Slot << "\n");
-
   }
 }
 
-void LocalSpiller::ClobberPhysReg(unsigned PhysReg,
-  std::map &SpillSlots,
-  std::multimap &PhysRegsAvailable) 
{
+/// ClobberPhysReg - This is called when the specified physreg changes
+/// value.  We use this to invalidate any info about stuff we thing lives in
+/// it and any of its aliases.
+void AvailableSpills::ClobberPhysReg(unsigned PhysReg) {
   for (const unsigned *AS = MRI->getAliasSet(PhysReg); *AS; ++AS)
-ClobberPhysRegOnly(*AS, SpillSlots, PhysRegsAvailable);
-  ClobberPhysRegOnly(PhysReg, SpillSlots, PhysRegsAvailable);
+ClobberPhysRegOnly(*AS);
+  ClobberPhysRegOnly(PhysReg);
 }
 
 /// ModifyStackSlot - This method is called when the value in a stack slot
 /// changes.  This removes information about which register the previous value
 /// for this slot lives in (as the previous value is dead now).
-void LocalSpiller::ModifyStackSlot(int Slot, std::map 
&SpillSlots,
-   

[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-02 Thread Jeff Cohen


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.50 -> 1.51
---
Log message:

Fix VC++ compilation error caused by using a std::map iterator variable to 
receive
a std::multimap iterator value.  For some reason, GCC doesn't have a problem 
with this.


---
Diffs of the changes:  (+1 -1)

 VirtRegMap.cpp |2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.50 
llvm/lib/CodeGen/VirtRegMap.cpp:1.51
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.50Thu Feb  2 21:16:14 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb  2 21:48:54 2006
@@ -234,7 +234,7 @@
 void LocalSpiller::ClobberPhysRegOnly(unsigned PhysReg,
   std::map &SpillSlots,
   std::multimap &PhysRegsAvailable) 
{
-  std::map::iterator I = PhysRegsAvailable.lower_bound(PhysReg);
+  std::multimap::iterator I = 
PhysRegsAvailable.lower_bound(PhysReg);
   while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
 int Slot = I->second;
 PhysRegsAvailable.erase(I++);



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-02 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.49 -> 1.50
---
Log message:

Remove move copies and dead stuff by not clobbering the result reg of a noop 
copy.


---
Diffs of the changes:  (+21 -12)

 VirtRegMap.cpp |   33 +
 1 files changed, 21 insertions(+), 12 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.49 
llvm/lib/CodeGen/VirtRegMap.cpp:1.50
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.49Thu Feb  2 21:06:49 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb  2 21:16:14 2006
@@ -607,6 +607,15 @@
   }
 
   if (!OpTakenCareOf) {
+// Check to see if this is a noop copy.  If so, eliminate the
+// instruction before considering the dest reg to be changed.
+unsigned Src, Dst;
+if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
+  ++NumDCE;
+  DEBUG(std::cerr << "Removing now-noop copy: " << MI);
+  MBB.erase(&MI);
+  goto ProcessNextInst;
+}
 ClobberPhysReg(VirtReg, SpillSlotsAvailable, PhysRegsAvailable);
 continue;
   }
@@ -631,6 +640,18 @@
 DEBUG(std::cerr << "Store:\t" << *next(MII));
 MI.SetMachineOperandReg(i, PhysReg);
 
+// Check to see if this is a noop copy.  If so, eliminate the
+// instruction before considering the dest reg to be changed.
+{
+  unsigned Src, Dst;
+  if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
+++NumDCE;
+DEBUG(std::cerr << "Removing now-noop copy: " << MI);
+MBB.erase(&MI);
+goto ProcessNextInst;
+  }
+}
+
 // If there is a dead store to this stack slot, nuke it now.
 MachineInstr *&LastStore = MaybeDeadStores[StackSlot];
 if (LastStore) {
@@ -654,18 +675,6 @@
 ++NumStores;
   }
 }
- 
-// Okay, the instruction has been completely processed, input and output 
-// registers have been added.  As a final sanity check, make sure this is
-// not a noop-copy.  If it is, nuke it.
-{
-  unsigned Src, Dst;
-  if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
-++NumDCE;
-DEBUG(std::cerr << "Removing now-noop copy: " << MI);
-MBB.erase(&MI);
-  }
-}
   ProcessNextInst:
 MII = NextMII;
   }



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-02 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.48 -> 1.49
---
Log message:

Simplify some code


---
Diffs of the changes:  (+40 -45)

 VirtRegMap.cpp |   85 ++---
 1 files changed, 40 insertions(+), 45 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.48 
llvm/lib/CodeGen/VirtRegMap.cpp:1.49
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.48Thu Feb  2 20:02:59 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb  2 21:06:49 2006
@@ -593,7 +593,6 @@
   if (MO.isRegister() && MO.getReg() && MO.isDef()) {
 unsigned VirtReg = MO.getReg();
 
-bool TakenCareOf = false;
 if (!MRegisterInfo::isVirtualRegister(VirtReg)) {
   // Check to see if this is a def-and-use vreg operand that we do need
   // to insert a store for.
@@ -609,54 +608,50 @@
 
   if (!OpTakenCareOf) {
 ClobberPhysReg(VirtReg, SpillSlotsAvailable, PhysRegsAvailable);
-TakenCareOf = true;
+continue;
   }
 }
 
-if (!TakenCareOf) {
-  // The only vregs left are stack slot definitions.
-  int StackSlot = VRM.getStackSlot(VirtReg);
-  const TargetRegisterClass *RC =
-MBB.getParent()->getSSARegMap()->getRegClass(VirtReg);
-  unsigned PhysReg;
-
-  // If this is a def&use operand, and we used a different physreg for
-  // it than the one assigned, make sure to execute the store from the
-  // correct physical register.
-  if (MO.getReg() == VirtReg)
-PhysReg = VRM.getPhys(VirtReg);
-  else
-PhysReg = MO.getReg();
-
-  PhysRegsUsed[PhysReg] = true;
-  MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC);
-  DEBUG(std::cerr << "Store:\t" << *next(MII));
-  MI.SetMachineOperandReg(i, PhysReg);
-
-  // If there is a dead store to this stack slot, nuke it now.
-  MachineInstr *&LastStore = MaybeDeadStores[StackSlot];
-  if (LastStore) {
-DEBUG(std::cerr << " Killed store:\t" << *LastStore);
-++NumDSE;
-MBB.erase(LastStore);
-  }
-  LastStore = next(MII);
-
-  // If the stack slot value was previously available in some other
-  // register, change it now.  Otherwise, make the register available,
-  // in PhysReg.
-  ModifyStackSlot(StackSlot, SpillSlotsAvailable, PhysRegsAvailable);
-  ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable);
-
-  PhysRegsAvailable.insert(std::make_pair(PhysReg, StackSlot));
-  SpillSlotsAvailable[StackSlot] = PhysReg;
-  DEBUG(std::cerr << "Updating SS#" << StackSlot <<" in physreg "
-  << MRI->getName(PhysReg) << " for virtreg #"
-  << VirtReg << "\n");
-
-  ++NumStores;
-  VirtReg = PhysReg;
+// The only vregs left are stack slot definitions.
+int StackSlot = VRM.getStackSlot(VirtReg);
+const TargetRegisterClass *RC =
+  MBB.getParent()->getSSARegMap()->getRegClass(VirtReg);
+unsigned PhysReg;
+
+// If this is a def&use operand, and we used a different physreg for
+// it than the one assigned, make sure to execute the store from the
+// correct physical register.
+if (MO.getReg() == VirtReg)
+  PhysReg = VRM.getPhys(VirtReg);
+else
+  PhysReg = MO.getReg();
+
+PhysRegsUsed[PhysReg] = true;
+MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC);
+DEBUG(std::cerr << "Store:\t" << *next(MII));
+MI.SetMachineOperandReg(i, PhysReg);
+
+// If there is a dead store to this stack slot, nuke it now.
+MachineInstr *&LastStore = MaybeDeadStores[StackSlot];
+if (LastStore) {
+  DEBUG(std::cerr << " Killed store:\t" << *LastStore);
+  ++NumDSE;
+  MBB.erase(LastStore);
 }
+LastStore = next(MII);
+
+// If the stack slot value was previously available in some other
+// register, change it now.  Otherwise, make the register available,
+// in PhysReg.
+ModifyStackSlot(StackSlot, SpillSlotsAvailable, PhysRegsAvailable);
+ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable);
+
+PhysRegsAvailable.insert(std::make_pair(PhysReg, StackSlot));
+SpillSlotsAvailable[StackSlot] = PhysReg;
+DEBUG(std::cerr << "Updating SS#" << StackSlot <<" in physreg "
+<< MRI->getName(PhysReg) << " for virtreg #"
+<< VirtReg << "\n");
+++NumStores;
   }
 }
  



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-02 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.47 -> 1.48
---
Log message:

Add code that checks for noop copies, which triggers when either:
1. a target doesn't know how to fold load/stores into copies, or
2. the spiller rewrites the input to a copy to the same register as the dest
   instead of to the reloaded reg.

This will be moved/improved in the near future, but allows elimination of
some ancient x86 hacks.  This eliminates 92 copies from SMG2000 on X86 and
163 copies from 252.eon.



---
Diffs of the changes:  (+13 -0)

 VirtRegMap.cpp |   13 +
 1 files changed, 13 insertions(+)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.47 
llvm/lib/CodeGen/VirtRegMap.cpp:1.48
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.47Thu Feb  2 18:36:31 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb  2 20:02:59 2006
@@ -38,6 +38,7 @@
   Statistic<> NumLoads ("spiller", "Number of loads added");
   Statistic<> NumReused("spiller", "Number of values reused");
   Statistic<> NumDSE   ("spiller", "Number of dead stores elided");
+  Statistic<> NumDCE   ("spiller", "Number of copies elided");
 
   enum SpillerName { simple, local };
 
@@ -658,6 +659,18 @@
 }
   }
 }
+ 
+// Okay, the instruction has been completely processed, input and output 
+// registers have been added.  As a final sanity check, make sure this is
+// not a noop-copy.  If it is, nuke it.
+{
+  unsigned Src, Dst;
+  if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
+++NumDCE;
+DEBUG(std::cerr << "Removing now-noop copy: " << MI);
+MBB.erase(&MI);
+  }
+}
   ProcessNextInst:
 MII = NextMII;
   }



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-02 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.46 -> 1.47
---
Log message:

Physregs may hold multiple stack slot values at the same time.  Keep track
of this, and use it to our advantage (bwahahah).  This allows us to eliminate 
another
60 instructions from smg2000 on PPC (probably significantly more on X86).  A 
common
old-new diff looks like this:

stw r2, 3304(r1)
-   lwz r2, 3192(r1)
stw r2, 3300(r1)
-   lwz r2, 3192(r1)
stw r2, 3296(r1)
-   lwz r2, 3192(r1)
stw r2, 3200(r1)
-   lwz r2, 3192(r1)
stw r2, 3196(r1)
-   lwz r2, 3192(r1)
+   or r2, r2, r2
stw r2, 3188(r1)

and

-   lwz r31, 604(r1)
-   lwz r13, 604(r1)
-   lwz r14, 604(r1)
-   lwz r15, 604(r1)
-   lwz r16, 604(r1)
-   lwz r30, 604(r1)
+   or r31, r30, r30
+   or r13, r30, r30
+   or r14, r30, r30
+   or r15, r30, r30
+   or r16, r30, r30
+   or r30, r30, r30

Removal of the R = R copies is coming next...



---
Diffs of the changes:  (+49 -37)

 VirtRegMap.cpp |   86 -
 1 files changed, 49 insertions(+), 37 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.46 
llvm/lib/CodeGen/VirtRegMap.cpp:1.47
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.46Thu Feb  2 17:29:36 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb  2 18:36:31 2006
@@ -222,36 +222,60 @@
   private:
 void RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM);
 void ClobberPhysReg(unsigned PR, std::map &SpillSlots,
-std::map &PhysRegs);
+std::multimap &PhysRegs);
 void ClobberPhysRegOnly(unsigned PR, std::map &SpillSlots,
-std::map &PhysRegs);
+std::multimap &PhysRegs);
+void ModifyStackSlot(int Slot, std::map &SpillSlots,
+ std::multimap &PhysRegs);
   };
 }
 
 void LocalSpiller::ClobberPhysRegOnly(unsigned PhysReg,
   std::map &SpillSlots,
-  std::map &PhysRegs) {
-  std::map::iterator I = PhysRegs.find(PhysReg);
-  if (I != PhysRegs.end()) {
+  std::multimap &PhysRegsAvailable) 
{
+  std::map::iterator I = PhysRegsAvailable.lower_bound(PhysReg);
+  while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
 int Slot = I->second;
-PhysRegs.erase(I);
+PhysRegsAvailable.erase(I++);
 assert(SpillSlots[Slot] == PhysReg && "Bidirectional map mismatch!");
 SpillSlots.erase(Slot);
 DEBUG(std::cerr << "PhysReg " << MRI->getName(PhysReg)
-  << " clobbered, invalidating SS#" << Slot << "\n");
+<< " clobbered, invalidating SS#" << Slot << "\n");
 
   }
 }
 
 void LocalSpiller::ClobberPhysReg(unsigned PhysReg,
   std::map &SpillSlots,
-  std::map &PhysRegs) {
+  std::multimap &PhysRegsAvailable) 
{
   for (const unsigned *AS = MRI->getAliasSet(PhysReg); *AS; ++AS)
-ClobberPhysRegOnly(*AS, SpillSlots, PhysRegs);
-  ClobberPhysRegOnly(PhysReg, SpillSlots, PhysRegs);
+ClobberPhysRegOnly(*AS, SpillSlots, PhysRegsAvailable);
+  ClobberPhysRegOnly(PhysReg, SpillSlots, PhysRegsAvailable);
+}
+
+/// ModifyStackSlot - This method is called when the value in a stack slot
+/// changes.  This removes information about which register the previous value
+/// for this slot lives in (as the previous value is dead now).
+void LocalSpiller::ModifyStackSlot(int Slot, std::map 
&SpillSlots,
+  std::multimap &PhysRegsAvailable) 
{
+  std::map::iterator It = SpillSlots.find(Slot);
+  if (It == SpillSlots.end()) return;
+  unsigned Reg = It->second;
+  SpillSlots.erase(It);
+  
+  // This register may hold the value of multiple stack slots, only remove this
+  // stack slot from the set of values the register contains.
+  std::multimap::iterator I = 
PhysRegsAvailable.lower_bound(Reg);
+  for (; ; ++I) {
+assert(I != PhysRegsAvailable.end() && I->first == Reg &&
+   "Map inverse broken!");
+if (I->second == Slot) break;
+  }
+  PhysRegsAvailable.erase(I);
 }
 
 
+
 // ReusedOp - For each reused operand, we keep track of a bit of information, 
in
 // case we need to rollback upon processing a new operand.  See comments below.
 namespace {
@@ -289,8 +313,9 @@
   std::map SpillSlotsAvailable;
 
   // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating
-  // which physregs are in use holding a stack slot value.
-  std::map PhysRegsAvailable;
+  // which stack slot values are currently held by a physreg.  This is used to
+  // invalidate entries in SpillSlotsAvailable when a physreg is modified.
+  std::multimap PhysRegsAvailable;
 
   DEBUG(std::cerr << MBB.getBasicBlock()->getName() << ":\n");
 
@@ -427,12 +452

[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-02 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.45 -> 1.46
---
Log message:

Fix a deficiency in the spiller that Evan noticed.  In particular, consider
this code:

  store [stack slot #0],  R10
= add R14, [stack slot #0]

The spiller didn't know that the store made the value of [stackslot#0] available
in R10 *IF* the store came from a copy instruction with the store folded into 
it.

This patch teaches VirtRegMap to look at these stores and recognize the values
they make available.  In one case Evan provided, this code:

divsd %XMM0, %XMM1
movsd %XMM1, QWORD PTR [%ESP + 40]
1)  movsd QWORD PTR [%ESP + 48], %XMM1
2)  movsd %XMM1, QWORD PTR [%ESP + 48]
addsd %XMM1, %XMM0
3)  movsd QWORD PTR [%ESP + 48], %XMM1
movsd QWORD PTR [%ESP + 4], %XMM0

turns into:

divsd %XMM0, %XMM1
movsd %XMM1, QWORD PTR [%ESP + 40]
addsd %XMM1, %XMM0
3)  movsd QWORD PTR [%ESP + 48], %XMM1
movsd QWORD PTR [%ESP + 4], %XMM0

In this case, instruction #2 was removed because of the value made 
available by #1, and inst #1 was later deleted because it is now 
never used before the stack slot is redefined by #3.

This occurs here and there in a lot of code with high spilling, on PPC
most of the removed loads/stores are LSU-reject-causing loads, which is
nice.

On X86, things are much better (because it spills more), where we nuke
about 1% of the instructions from SMG2000 and several hundred from eon.

More improvements to come...





---
Diffs of the changes:  (+31 -1)

 VirtRegMap.cpp |   32 +++-
 1 files changed, 31 insertions(+), 1 deletion(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.45 
llvm/lib/CodeGen/VirtRegMap.cpp:1.46
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.45Thu Feb  2 14:12:13 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb  2 17:29:36 2006
@@ -284,7 +284,7 @@
 void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
 
   // SpillSlotsAvailable - This map keeps track of all of the spilled virtual
-  // register values that are still available, due to being loaded to stored 
to,
+  // register values that are still available, due to being loaded or stored 
to,
   // but not invalidated yet.
   std::map SpillSlotsAvailable;
 
@@ -535,6 +535,36 @@
   PhysRegsAvailable.erase(It->second);
   SpillSlotsAvailable.erase(It);
 }
+
+// If this is *just* a mod of the value, check to see if this is just a
+// store to the spill slot (i.e. the spill got merged into the copy). 
If
+// so, realize that the vreg is available now, and add the store to the
+// MaybeDeadStore info.
+int StackSlot;
+if (!(MR & VirtRegMap::isRef)) {
+  if (unsigned SrcReg = TII->isStoreToStackSlot(&MI, StackSlot)) {
+assert(MRegisterInfo::isPhysicalRegister(SrcReg) &&
+   "Src hasn't been allocated yet?");
+// Okay, this is certainly a store of SrcReg to [FrameIdx].  Mark
+// this as a potentially dead store in case there is a subsequent
+// store into the stack slot without a read from it.
+MaybeDeadStores[StackSlot] = &MI;
+
+// FIXME: PhysRegsAvailable is a 1-1 map, not a N-1 map, which 
means
+// that we have to *forget* that SrcReg contains the old value it
+// does.
+ClobberPhysRegOnly(SrcReg, SpillSlotsAvailable, PhysRegsAvailable);
+
+// If the stack slot value was previously available in some other
+// register, change it now.  Otherwise, make the register 
available,
+// in PhysReg.
+SpillSlotsAvailable[StackSlot] = SrcReg;
+PhysRegsAvailable[SrcReg] = StackSlot;
+DEBUG(std::cerr << "Updating SS#" << StackSlot << " in physreg "
+<< MRI->getName(SrcReg) << " for virtreg #"
+<< VirtReg << "\n" << MI);
+  }
+}
   }
 }
 



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

2006-02-02 Thread Chris Lattner


Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.44 -> 1.45
---
Log message:

Move isLoadFrom/StoreToStackSlot from MRegisterInfo to TargetInstrInfo,a far 
more logical place.  Other methods should also be moved if anyoneis interested. 
:)



---
Diffs of the changes:  (+3 -2)

 VirtRegMap.cpp |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.44 
llvm/lib/CodeGen/VirtRegMap.cpp:1.45
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.44Sun Jan 22 17:41:00 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb  2 14:12:13 2006
@@ -490,8 +490,9 @@
   // straight load from the virt reg slot.
   if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) {
 int FrameIdx;
-if (unsigned DestReg = MRI->isLoadFromStackSlot(&MI, FrameIdx)) {
-  // If this spill slot is available, insert a copy for it!
+if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
+  // If this spill slot is available, turn it into a copy (or nothing)
+  // instead of leaving it as a load!
   std::map::iterator It = SpillSlotsAvailable.find(SS);
   if (FrameIdx == SS && It != SpillSlotsAvailable.end()) {
 DEBUG(std::cerr << "Promoted Load To Copy: " << MI);



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits