[llvm-commits] [llvm] r74601 - in /llvm/trunk: include/llvm/CodeGen/RegisterScavenging.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/RegisterScavenging.cpp lib/CodeGen/SimpleRegisterCoalescing.cpp test/CodeGen/ARM/2009-06-30-RegScavengerAssert5.ll

Evan Cheng evan.cheng at apple.com
Wed Jul 1 01:19:46 PDT 2009


Author: evancheng
Date: Wed Jul  1 03:19:36 2009
New Revision: 74601

URL: http://llvm.org/viewvc/llvm-project?rev=74601&view=rev
Log:
Remove special handling of implicit_def. Fix a couple more bugs in liveintervalanalysis and coalescer handling of implicit_def.

Note, isUndef marker must be placed even on implicit_def def operand or else the scavenger will not ignore it. This is necessary because -O0 path does not use liveintervalanalysis, it treats implicit_def just like any other def.

Added:
    llvm/trunk/test/CodeGen/ARM/2009-06-30-RegScavengerAssert5.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h
    llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/trunk/lib/CodeGen/RegisterScavenging.cpp
    llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp

Modified: llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h?rev=74601&r1=74600&r2=74601&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h (original)
+++ llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h Wed Jul  1 03:19:36 2009
@@ -69,10 +69,6 @@
   /// available, unset means the register is currently being used.
   BitVector RegsAvailable;
 
-  /// ImplicitDefed - If bit is set that means the register is defined by an
-  /// implicit_def instructions. That means it can be clobbered at will.
-  BitVector ImplicitDefed;
-
   /// CurrDist - Distance from MBB entry to the current instruction MBBI.
   ///
   unsigned CurrDist;
@@ -117,25 +113,18 @@
   bool isUsed(unsigned Reg) const   { return !RegsAvailable[Reg]; }
   bool isUnused(unsigned Reg) const { return RegsAvailable[Reg]; }
 
-  bool isImplicitlyDefined(unsigned Reg) const { return ImplicitDefed[Reg]; }
-
   /// getRegsUsed - return all registers currently in use in used.
   void getRegsUsed(BitVector &used, bool includeReserved);
 
   /// setUsed / setUnused - Mark the state of one or a number of registers.
   ///
-  void setUsed(unsigned Reg, bool ImpDef = false);
-  void setUsed(BitVector &Regs, bool ImpDef = false) {
+  void setUsed(unsigned Reg);
+  void setUsed(BitVector &Regs) {
     RegsAvailable &= ~Regs;
-    if (ImpDef)
-      ImplicitDefed |= Regs;
-    else
-      ImplicitDefed &= ~Regs;
   }
   void setUnused(unsigned Reg, const MachineInstr *MI);
   void setUnused(BitVector &Regs) {
     RegsAvailable |= Regs;
-    ImplicitDefed &= ~Regs;
   }
 
   /// FindUnusedReg - Find a unused register of the specified register class

Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=74601&r1=74600&r2=74601&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Jul  1 03:19:36 2009
@@ -124,7 +124,9 @@
         ImpDefMIs.push_back(MI);
         continue;
       }
-      for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
+
+      bool ChangedToImpDef = false;
+      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
         MachineOperand& MO = MI->getOperand(i);
         if (!MO.isReg() || !MO.isUse())
           continue;
@@ -133,16 +135,35 @@
           continue;
         if (!ImpDefRegs.count(Reg))
           continue;
+        // Use is a copy, just turn it into an implicit_def.
+        unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+        if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
+            Reg == SrcReg) {
+          bool isKill = MO.isKill();
+          MI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
+          for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j)
+            MI->RemoveOperand(j);
+          if (isKill)
+            ImpDefRegs.erase(Reg);
+          ChangedToImpDef = true;
+          break;
+        }
+
         MO.setIsUndef();
         if (MO.isKill() || MI->isRegTiedToDefOperand(i))
           ImpDefRegs.erase(Reg);
       }
 
-      for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
-        MachineOperand& MO = MI->getOperand(i);
-        if (!MO.isReg() || !MO.isDef())
-          continue;
-        ImpDefRegs.erase(MO.getReg());
+      if (ChangedToImpDef) {
+        // Backtrack to process this new implicit_def.
+        --I;
+      } else {
+        for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
+          MachineOperand& MO = MI->getOperand(i);
+          if (!MO.isReg() || !MO.isDef())
+            continue;
+          ImpDefRegs.erase(MO.getReg());
+        }
       }
     }
 
@@ -155,33 +176,39 @@
         continue;
       if (!ImpDefRegs.count(Reg))
         continue;
-      bool HasLocalUse = false;
-      for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(Reg),
-             RE = mri_->reg_end(); RI != RE; ) {
-        MachineOperand &RMO = RI.getOperand();
-        MachineInstr *RMI = &*RI;
-        ++RI;
-        if (RMO.isDef()) {
-          // Don't expect another def of the same register.
-          assert(RMI == MI &&
-                 "Register with multiple defs including an implicit_def?");
-          continue;
+
+      // If there are multiple defs of the same register and at least one
+      // is not an implicit_def, do not insert implicit_def's before the
+      // uses.
+      bool Skip = false;
+      for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg),
+             DE = mri_->def_end(); DI != DE; ++DI) {
+        if (DI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) {
+          Skip = true;
+          break;
         }
+      }
+      if (Skip)
+        continue;
+
+      for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg),
+             UE = mri_->use_end(); UI != UE; ) {
+        MachineOperand &RMO = UI.getOperand();
+        MachineInstr *RMI = &*UI;
+        ++UI;
         MachineBasicBlock *RMBB = RMI->getParent();
-        if (RMBB == MBB) {
-          HasLocalUse = true;
+        if (RMBB == MBB)
           continue;
-        }
         const TargetRegisterClass* RC = mri_->getRegClass(Reg);
         unsigned NewVReg = mri_->createVirtualRegister(RC);
-        BuildMI(*RMBB, RMI, RMI->getDebugLoc(),
-                tii_->get(TargetInstrInfo::IMPLICIT_DEF), NewVReg);
+        MachineInstrBuilder MIB =
+          BuildMI(*RMBB, RMI, RMI->getDebugLoc(),
+                  tii_->get(TargetInstrInfo::IMPLICIT_DEF), NewVReg);
+        (*MIB).getOperand(0).setIsUndef();
         RMO.setReg(NewVReg);
         RMO.setIsUndef();
         RMO.setIsKill();
       }
-      if (!HasLocalUse)
-        MI->eraseFromParent();
     }
     ImpDefRegs.clear();
     ImpDefMIs.clear();

Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterScavenging.cpp?rev=74601&r1=74600&r2=74601&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/RegisterScavenging.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Wed Jul  1 03:19:36 2009
@@ -57,28 +57,22 @@
 }
 
 /// setUsed - Set the register and its sub-registers as being used.
-void RegScavenger::setUsed(unsigned Reg, bool ImpDef) {
+void RegScavenger::setUsed(unsigned Reg) {
   RegsAvailable.reset(Reg);
-  ImplicitDefed[Reg] = ImpDef;
 
   for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
-       unsigned SubReg = *SubRegs; ++SubRegs) {
+       unsigned SubReg = *SubRegs; ++SubRegs)
     RegsAvailable.reset(SubReg);
-    ImplicitDefed[SubReg] = ImpDef;
-  }
 }
 
 /// setUnused - Set the register and its sub-registers as being unused.
 void RegScavenger::setUnused(unsigned Reg, const MachineInstr *MI) {
   RegsAvailable.set(Reg);
-  ImplicitDefed.reset(Reg);
 
   for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
        unsigned SubReg = *SubRegs; ++SubRegs)
-    if (!RedefinesSuperRegPart(MI, Reg, TRI)) {
+    if (!RedefinesSuperRegPart(MI, Reg, TRI))
       RegsAvailable.set(SubReg);
-      ImplicitDefed.reset(SubReg);
-    }
 }
 
 void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
@@ -94,7 +88,6 @@
   if (!MBB) {
     NumPhysRegs = TRI->getNumRegs();
     RegsAvailable.resize(NumPhysRegs);
-    ImplicitDefed.resize(NumPhysRegs);
 
     // Create reserved registers bitvector.
     ReservedRegs = TRI->getReservedRegs(MF);
@@ -113,7 +106,6 @@
   ScavengeRestore = NULL;
   CurrDist = 0;
   DistanceMap.clear();
-  ImplicitDefed.reset();
 
   // All registers started out unused.
   RegsAvailable.set();
@@ -195,7 +187,10 @@
     ScavengeRestore = NULL;
   }
 
-  bool IsImpDef = MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF;
+#if 0
+  if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
+    return;
+#endif
 
   // Separate register operands into 3 classes: uses, defs, earlyclobbers.
   SmallVector<std::pair<const MachineOperand*,unsigned>, 4> UseMOs;
@@ -221,14 +216,7 @@
 
     assert(isUsed(Reg) && "Using an undefined register!");
 
-    // Kill of implicit_def defined registers are ignored. e.g.
-    // entry: 0x2029ab8, LLVM BB @0x1b06080, ID#0:
-    // Live Ins: %R0
-    //  %R0<def> = IMPLICIT_DEF
-    //  %R0<def> = IMPLICIT_DEF
-    //  STR %R0<kill>, %R0, %reg0, 0, 14, %reg0, Mem:ST(4,4) [0x1b06510 + 0]
-    //  %R1<def> = LDR %R0, %reg0, 24, 14, %reg0, Mem:LD(4,4) [0x1b065bc + 0]
-    if (MO.isKill() && !isReserved(Reg) && !isImplicitlyDefined(Reg)) {
+    if (MO.isKill() && !isReserved(Reg)) {
       KillRegs.set(Reg);
 
       // Mark sub-registers as used.
@@ -278,10 +266,9 @@
     // Implicit def is allowed to "re-define" any register. Similarly,
     // implicitly defined registers can be clobbered.
     assert((isReserved(Reg) || isUnused(Reg) ||
-            IsImpDef || isImplicitlyDefined(Reg) ||
             isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) &&
            "Re-defining a live register!");
-    setUsed(Reg, IsImpDef);
+    setUsed(Reg);
   }
 }
 

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

==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Wed Jul  1 03:19:36 2009
@@ -2669,19 +2669,28 @@
   CopyMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
   for (int i = CopyMI->getNumOperands() - 1, e = 0; i > e; --i)
     CopyMI->RemoveOperand(i);
+  CopyMI->getOperand(0).setIsUndef();
   bool NoUse = mri_->use_empty(SrcReg);
   if (NoUse) {
-    for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(SrcReg),
-           E = mri_->reg_end(); I != E; ) {
-      assert(I.getOperand().isDef());
-      MachineInstr *DefMI = &*I;
-      ++I;
+    for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(SrcReg),
+           RE = mri_->reg_end(); RI != RE; ) {
+      assert(RI.getOperand().isDef());
+      MachineInstr *DefMI = &*RI;
+      ++RI;
       // The implicit_def source has no other uses, delete it.
       assert(DefMI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF);
       li_->RemoveMachineInstrFromMaps(DefMI);
       DefMI->eraseFromParent();
     }
   }
+
+  // Mark uses of implicit_def isUndef.
+  for (MachineRegisterInfo::use_iterator RI = mri_->use_begin(DstReg),
+         RE = mri_->use_end(); RI != RE; ++RI) {
+    assert((*RI).getParent() == MBB);
+    RI.getOperand().setIsUndef();
+  }
+
   ++I;
   return true;
 }

Added: llvm/trunk/test/CodeGen/ARM/2009-06-30-RegScavengerAssert5.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-06-30-RegScavengerAssert5.ll?rev=74601&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/ARM/2009-06-30-RegScavengerAssert5.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/2009-06-30-RegScavengerAssert5.ll Wed Jul  1 03:19:36 2009
@@ -0,0 +1,99 @@
+; RUN: llvm-as < %s | llc -march=arm -mtriple=armv6-apple-darwin9
+
+ at XX = external global i32*		; <i32**> [#uses=1]
+
+define arm_apcscc void @SIM(i8* %A, i8* %B, i32 %M, i32 %N, i32 %K, [256 x i32]* %V, i32 %Q, i32 %R, i32 %nseq) nounwind {
+entry:
+	br i1 undef, label %bb5, label %bb
+
+bb:		; preds = %bb, %entry
+	br label %bb
+
+bb5:		; preds = %entry
+	br i1 undef, label %bb6, label %bb8
+
+bb6:		; preds = %bb6, %bb5
+	br i1 undef, label %bb8, label %bb6
+
+bb8:		; preds = %bb6, %bb5
+	br label %bb15
+
+bb9:		; preds = %bb15
+	br i1 undef, label %bb10, label %bb11
+
+bb10:		; preds = %bb9
+	unreachable
+
+bb11:		; preds = %bb9
+	br i1 undef, label %bb15, label %bb12
+
+bb12:		; preds = %bb11
+	%0 = load i32** @XX, align 4		; <i32*> [#uses=0]
+	br label %bb228.i
+
+bb74.i:		; preds = %bb228.i
+	br i1 undef, label %bb138.i, label %bb145.i
+
+bb138.i:		; preds = %bb74.i
+	br label %bb145.i
+
+bb145.i:		; preds = %bb228.i, %bb138.i, %bb74.i
+	br i1 undef, label %bb146.i, label %bb151.i
+
+bb146.i:		; preds = %bb145.i
+	br i1 undef, label %bb228.i, label %bb151.i
+
+bb151.i:		; preds = %bb146.i, %bb145.i
+	br i1 undef, label %bb153.i, label %bb228.i
+
+bb153.i:		; preds = %bb151.i
+	br i1 undef, label %bb220.i, label %bb.nph.i98
+
+bb.nph.i98:		; preds = %bb153.i
+	br label %bb158.i
+
+bb158.i:		; preds = %bb218.i, %bb.nph.i98
+	%1 = sub i32 undef, undef		; <i32> [#uses=4]
+	%2 = sub i32 undef, undef		; <i32> [#uses=1]
+	br i1 undef, label %bb168.i, label %bb160.i
+
+bb160.i:		; preds = %bb158.i
+	br i1 undef, label %bb161.i, label %bb168.i
+
+bb161.i:		; preds = %bb160.i
+	br i1 undef, label %bb168.i, label %bb163.i
+
+bb163.i:		; preds = %bb161.i
+	br i1 undef, label %bb167.i, label %bb168.i
+
+bb167.i:		; preds = %bb163.i
+	br label %bb168.i
+
+bb168.i:		; preds = %bb167.i, %bb163.i, %bb161.i, %bb160.i, %bb158.i
+	%f.5.i = phi i32 [ %1, %bb167.i ], [ %2, %bb158.i ], [ %1, %bb160.i ], [ %1, %bb161.i ], [ %1, %bb163.i ]		; <i32> [#uses=1]
+	%c.14.i = select i1 undef, i32 %f.5.i, i32 undef		; <i32> [#uses=1]
+	store i32 %c.14.i, i32* undef, align 4
+	store i32 undef, i32* null, align 4
+	br i1 undef, label %bb211.i, label %bb218.i
+
+bb211.i:		; preds = %bb168.i
+	br label %bb218.i
+
+bb218.i:		; preds = %bb211.i, %bb168.i
+	br i1 undef, label %bb220.i, label %bb158.i
+
+bb220.i:		; preds = %bb218.i, %bb153.i
+	br i1 undef, label %bb221.i, label %bb228.i
+
+bb221.i:		; preds = %bb220.i
+	br label %bb228.i
+
+bb228.i:		; preds = %bb221.i, %bb220.i, %bb151.i, %bb146.i, %bb12
+	br i1 undef, label %bb74.i, label %bb145.i
+
+bb15:		; preds = %bb11, %bb8
+	br i1 undef, label %return, label %bb9
+
+return:		; preds = %bb15
+	ret void
+}





More information about the llvm-commits mailing list