Fix for PR1406:
authorEvan Cheng <evan.cheng@apple.com>
Mon, 14 May 2007 21:10:05 +0000 (21:10 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Mon, 14 May 2007 21:10:05 +0000 (21:10 +0000)
v1 =
r2 = move v1
   = op r2<kill>
...
r2 = move v1
   = op r2<kill>

Clear the first r2 kill if v1 and r2 are joined.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37050 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/LiveIntervalAnalysis.h
lib/CodeGen/LiveIntervalAnalysis.cpp

index 26a244fcb0e99b8fd716b217971eeaf660540531..10f60f4f05c156c8e9ecf6f82c682388e65770b5 100644 (file)
@@ -271,7 +271,7 @@ namespace llvm {
     /// lastRegisterUse - Returns the last use of the specific register between
     /// cycles Start and End. It also returns the use operand by reference. It
     /// returns NULL if there are no uses.
-    MachineInstr *lastRegisterUse(unsigned Reg, unsigned Start, unsigned End,
+    MachineInstr *lastRegisterUse(unsigned Start, unsigned End, unsigned Reg,
                                   MachineOperand *&MOU);
 
     /// findDefOperand - Returns the MachineOperand that is a def of the specific
@@ -282,6 +282,10 @@ namespace llvm {
     /// register of the specific instruction.
     void unsetRegisterKill(MachineInstr *MI, unsigned Reg);
 
+    /// unsetRegisterKills - Unset IsKill property of all uses of specific register
+    /// between cycles Start and End.
+    void unsetRegisterKills(unsigned Start, unsigned End, unsigned Reg);
+
     /// hasRegisterDef - True if the instruction defines the specific register.
     ///
     bool hasRegisterDef(MachineInstr *MI, unsigned Reg);
index c816baffdbf21f07451e68dbe9dd86dfdd0d6d3d..a996aea4816ada8f163c1e45d7654a1e5eef8543 100644 (file)
@@ -977,7 +977,7 @@ bool LiveIntervals::JoinCopy(MachineInstr *CopyMI,
       isDead = false;
     } else {
       MachineOperand *MOU;
-      MachineInstr *LastUse= lastRegisterUse(repSrcReg, SrcStart, CopyIdx, MOU);
+      MachineInstr *LastUse= lastRegisterUse(SrcStart, CopyIdx, repSrcReg, MOU);
       if (LastUse) {
         // Shorten the liveinterval to the end of last use.
         MOU->setIsKill();
@@ -1072,6 +1072,11 @@ bool LiveIntervals::JoinCopy(MachineInstr *CopyMI,
   // we have to update any aliased register's live ranges to indicate that they
   // have clobbered values for this range.
   if (MRegisterInfo::isPhysicalRegister(repDstReg)) {
+    // Unset unnecessary kills.
+    for (LiveInterval::Ranges::const_iterator I = SrcInt.begin(),
+           E = SrcInt.end(); I != E; ++I)
+      unsetRegisterKills(I->start, I->end, repDstReg);
+
     // Update the liveintervals of sub-registers.
     for (const unsigned *AS = mri_->getSubRegisters(repDstReg); *AS; ++AS)
         getInterval(*AS).MergeInClobberRanges(SrcInt);
@@ -1632,7 +1637,7 @@ bool LiveIntervals::differingRegisterClasses(unsigned RegA,
 /// cycles Start and End. It also returns the use operand by reference. It
 /// returns NULL if there are no uses.
 MachineInstr *
-LiveIntervals::lastRegisterUse(unsigned Reg, unsigned Start, unsigned End,
+LiveIntervals::lastRegisterUse(unsigned Start, unsigned End, unsigned Reg,
                                MachineOperand *&MOU) {
   int e = (End-1) / InstrSlots::NUM * InstrSlots::NUM;
   int s = Start;
@@ -1685,6 +1690,34 @@ void LiveIntervals::unsetRegisterKill(MachineInstr *MI, unsigned Reg) {
   }
 }
 
+/// unsetRegisterKills - Unset IsKill property of all uses of specific register
+/// between cycles Start and End.
+void LiveIntervals::unsetRegisterKills(unsigned Start, unsigned End,
+                                       unsigned Reg) {
+  int e = (End-1) / InstrSlots::NUM * InstrSlots::NUM;
+  int s = Start;
+  while (e >= s) {
+    // Skip deleted instructions
+    MachineInstr *MI = getInstructionFromIndex(e);
+    while ((e - InstrSlots::NUM) >= s && !MI) {
+      e -= InstrSlots::NUM;
+      MI = getInstructionFromIndex(e);
+    }
+    if (e < s || MI == NULL)
+      return;
+
+    for (unsigned i = 0, NumOps = MI->getNumOperands(); i != NumOps; ++i) {
+      MachineOperand &MO = MI->getOperand(i);
+      if (MO.isReg() && MO.isUse() && MO.isKill() && MO.getReg() &&
+          mri_->regsOverlap(rep(MO.getReg()), Reg)) {
+        MO.unsetIsKill();
+      }
+    }
+
+    e -= InstrSlots::NUM;
+  }
+}
+
 /// hasRegisterDef - True if the instruction defines the specific register.
 ///
 bool LiveIntervals::hasRegisterDef(MachineInstr *MI, unsigned Reg) {