[llvm-commits] [llvm] r47966 - in /llvm/trunk: lib/CodeGen/SimpleRegisterCoalescing.cpp lib/CodeGen/SimpleRegisterCoalescing.h test/CodeGen/PowerPC/2008-03-05-RegScavengerAssert.ll

Evan Cheng evan.cheng at apple.com
Wed Mar 5 14:09:43 PST 2008


Author: evancheng
Date: Wed Mar  5 16:09:42 2008
New Revision: 47966

URL: http://llvm.org/viewvc/llvm-project?rev=47966&view=rev
Log:
Fix a coalescer bug wrt how dead copy interval is shortened.

Added:
    llvm/trunk/test/CodeGen/PowerPC/2008-03-05-RegScavengerAssert.ll
Modified:
    llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
    llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h

Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=47966&r1=47965&r2=47966&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Wed Mar  5 16:09:42 2008
@@ -451,6 +451,30 @@
   }
 }
 
+/// ShortenDeadCopyLiveRange - Shorten a live range as it's artificially
+/// extended by a dead copy. Mark the last use (if any) of the val# as kill
+/// as ends the live range there. If there isn't another use, then this
+/// live range is dead.
+void SimpleRegisterCoalescing::ShortenDeadCopyLiveRange(LiveInterval &li,
+                                                        MachineInstr *CopyMI) {
+  unsigned CopyIdx = li_->getInstructionIndex(CopyMI);
+  LiveInterval::iterator MLR =
+    li.FindLiveRangeContaining(li_->getDefIndex(CopyIdx));
+  unsigned RemoveStart = MLR->start;
+  unsigned RemoveEnd = MLR->end;
+  unsigned LastUseIdx;
+  MachineOperand *LastUse = lastRegisterUse(RemoveStart, CopyIdx, li.reg,
+                                            LastUseIdx);
+  if (LastUse) {
+    // Shorten the liveinterval to the end of last use.
+    LastUse->setIsKill();
+    RemoveStart = li_->getDefIndex(LastUseIdx);
+  }
+  li.removeRange(RemoveStart, RemoveEnd, true);
+  if (li.empty())
+    li_->removeInterval(li.reg);
+}
+
 /// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
 /// which are the src/dst of the copy instruction CopyMI.  This returns true
 /// if the copy was successfully coalesced away. If it is not currently
@@ -599,23 +623,22 @@
       SrcInt.FindLiveRangeContaining(li_->getUseIndex(CopyIdx));
     RemoveStart = SrcStart = SrcLR->start;
     RemoveEnd   = SrcEnd   = SrcLR->end;
-    // The instruction which defines the src is only truly dead if there are
-    // no intermediate uses and there isn't a use beyond the copy.
-    // FIXME: find the last use, mark is kill and shorten the live range.
     if (SrcEnd > li_->getDefIndex(CopyIdx)) {
+      // If there are other uses of SrcReg beyond the copy, there is nothing to do.
       isDead = false;
     } else {
       unsigned LastUseIdx;
       MachineOperand *LastUse =
         lastRegisterUse(SrcStart, CopyIdx, SrcReg, LastUseIdx);
       if (LastUse) {
-        // Shorten the liveinterval to the end of last use.
+        // There are uses before the copy, just shorten the live range to the end
+        // of last use.
         LastUse->setIsKill();
         isDead = false;
         isShorten = true;
         RemoveStart = li_->getDefIndex(LastUseIdx);
-        RemoveEnd = SrcEnd;
       } else {
+        // This live range is truly dead. Remove it.
         MachineInstr *SrcMI = li_->getInstructionFromIndex(SrcStart);
         if (SrcMI && SrcMI->modifiesRegister(SrcReg, tri_))
           // A dead def should have a single cycle interval.
@@ -1531,16 +1554,10 @@
       if (tii_->isMoveInstr(*mii, srcReg, dstReg) && srcReg == dstReg) {
         // remove from def list
         LiveInterval &RegInt = li_->getOrCreateInterval(srcReg);
-        MachineOperand *MO = mii->findRegisterDefOperand(dstReg, false);
         // If def of this move instruction is dead, remove its live range from
         // the dstination register's live interval.
-        if (MO->isDead()) {
-          unsigned MoveIdx = li_->getDefIndex(li_->getInstructionIndex(mii));
-          LiveInterval::iterator MLR = RegInt.FindLiveRangeContaining(MoveIdx);
-          RegInt.removeRange(MLR->start, MoveIdx+1, true);
-          if (RegInt.empty())
-            li_->removeInterval(srcReg);
-        }
+        if (mii->registerDefIsDead(dstReg))
+          ShortenDeadCopyLiveRange(RegInt, mii);
         li_->RemoveMachineInstrFromMaps(mii);
         mii = mbbi->erase(mii);
         ++numPeep;

Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h?rev=47966&r1=47965&r2=47966&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h Wed Mar  5 16:09:42 2008
@@ -201,6 +201,12 @@
     /// subregister.
     void UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg, unsigned SubIdx);
 
+    /// ShortenDeadCopyLiveRange - Shorten a live range as it's artificially
+    /// extended by a dead copy. Mark the last use (if any) of the val# as kill
+    /// as ends the live range there. If there isn't another use, then this
+    /// live range is dead.
+    void ShortenDeadCopyLiveRange(LiveInterval &li, MachineInstr *CopyMI);
+
     /// lastRegisterUse - Returns the last use of the specific register between
     /// cycles Start and End or NULL if there are no uses.
     MachineOperand *lastRegisterUse(unsigned Start, unsigned End, unsigned Reg,

Added: llvm/trunk/test/CodeGen/PowerPC/2008-03-05-RegScavengerAssert.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2008-03-05-RegScavengerAssert.ll?rev=47966&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/2008-03-05-RegScavengerAssert.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/2008-03-05-RegScavengerAssert.ll Wed Mar  5 16:09:42 2008
@@ -0,0 +1,18 @@
+; RUN: llvm-as < %s | llc -mtriple=powerpc-apple-darwin -enable-ppc-regscavenger
+
+declare i8* @bar(i32)
+
+define void @foo(i8* %pp) nounwind  {
+entry:
+	%tmp2 = tail call i8* @bar( i32 14 ) nounwind 		; <i8*> [#uses=0]
+	%tmp28 = bitcast i8* %pp to void ()**		; <void ()**> [#uses=1]
+	%tmp38 = load void ()** %tmp28, align 4		; <void ()*> [#uses=2]
+	br i1 false, label %bb34, label %bb25
+bb25:		; preds = %entry
+	%tmp30 = bitcast void ()* %tmp38 to void (i8*)*		; <void (i8*)*> [#uses=1]
+	tail call void %tmp30( i8* null ) nounwind 
+	ret void
+bb34:		; preds = %entry
+	tail call void %tmp38( ) nounwind 
+	ret void
+}





More information about the llvm-commits mailing list