[llvm-commits] [llvm] r71606 - in /llvm/trunk: lib/CodeGen/RegAllocLinearScan.cpp lib/CodeGen/VirtRegRewriter.cpp test/CodeGen/X86/2007-03-01-SpillerCrash.ll

Evan Cheng evan.cheng at apple.com
Tue May 12 16:07:01 PDT 2009


Author: evancheng
Date: Tue May 12 18:07:00 2009
New Revision: 71606

URL: http://llvm.org/viewvc/llvm-project?rev=71606&view=rev
Log:
Teach TransferDeadness to delete truly dead instructions if they do not produce side effects.

Modified:
    llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
    llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp
    llvm/trunk/test/CodeGen/X86/2007-03-01-SpillerCrash.ll

Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=71606&r1=71605&r2=71606&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Tue May 12 18:07:00 2009
@@ -350,29 +350,44 @@
   if (!vni->def || vni->def == ~1U || vni->def == ~0U)
     return Reg;
   MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
-  unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+  unsigned SrcReg, DstReg, SrcSubReg, DstSubReg, PhysReg;
   if (!CopyMI ||
       !tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg))
     return Reg;
+  PhysReg = SrcReg;
   if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
     if (!vrm_->isAssignedReg(SrcReg))
       return Reg;
-    else
-      SrcReg = vrm_->getPhys(SrcReg);
+    PhysReg = vrm_->getPhys(SrcReg);
   }
-  if (Reg == SrcReg)
+  if (Reg == PhysReg)
     return Reg;
 
   const TargetRegisterClass *RC = mri_->getRegClass(cur.reg);
-  if (!RC->contains(SrcReg))
+  if (!RC->contains(PhysReg))
     return Reg;
 
   // Try to coalesce.
-  if (!li_->conflictsWithPhysRegDef(cur, *vrm_, SrcReg)) {
-    DOUT << "Coalescing: " << cur << " -> " << tri_->getName(SrcReg)
+  if (!li_->conflictsWithPhysRegDef(cur, *vrm_, PhysReg)) {
+    DOUT << "Coalescing: " << cur << " -> " << tri_->getName(PhysReg)
          << '\n';
     vrm_->clearVirt(cur.reg);
-    vrm_->assignVirt2Phys(cur.reg, SrcReg);
+    vrm_->assignVirt2Phys(cur.reg, PhysReg);
+
+    // Remove unnecessary kills since a copy does not clobber the register.
+    if (li_->hasInterval(SrcReg)) {
+      LiveInterval &SrcLI = li_->getInterval(SrcReg);
+      for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(cur.reg),
+             E = mri_->reg_end(); I != E; ++I) {
+        MachineOperand &O = I.getOperand();
+        if (!O.isUse() || !O.isKill())
+          continue;
+        MachineInstr *MI = &*I;
+        if (SrcLI.liveAt(li_->getDefIndex(li_->getInstructionIndex(MI))))
+          O.setIsKill(false);
+      }
+    }
+
     ++NumCoalesce;
     return SrcReg;
   }

Modified: llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp?rev=71606&r1=71605&r2=71606&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Tue May 12 18:07:00 2009
@@ -851,6 +851,14 @@
   }
 }
 
+namespace {
+  struct RefSorter {
+    bool operator()(const std::pair<MachineInstr*, int> &A,
+                    const std::pair<MachineInstr*, int> &B) {
+      return A.second < B.second;
+    }
+  };
+}
 
 // ***************************** //
 // Local Spiller Implementation  //
@@ -1313,9 +1321,10 @@
   /// removed. Find the last def or use and mark it as dead / kill.
   void TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
                         unsigned Reg, BitVector &RegKills,
-                        std::vector<MachineOperand*> &KillOps) {
-    int LastUDDist = -1;
-    MachineInstr *LastUDMI = NULL;
+                        std::vector<MachineOperand*> &KillOps,
+                        VirtRegMap &VRM) {
+    SmallPtrSet<MachineInstr*, 4> Seens;
+    SmallVector<std::pair<MachineInstr*, int>,8> Refs;
     for (MachineRegisterInfo::reg_iterator RI = RegInfo->reg_begin(Reg),
            RE = RegInfo->reg_end(); RI != RE; ++RI) {
       MachineInstr *UDMI = &*RI;
@@ -1324,13 +1333,18 @@
       DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(UDMI);
       if (DI == DistanceMap.end() || DI->second > CurDist)
         continue;
-      if ((int)DI->second < LastUDDist)
-        continue;
-      LastUDDist = DI->second;
-      LastUDMI = UDMI;
+      if (Seens.insert(UDMI))
+        Refs.push_back(std::make_pair(UDMI, DI->second));
     }
 
-    if (LastUDMI) {
+    if (Refs.empty())
+      return;
+    std::sort(Refs.begin(), Refs.end(), RefSorter());
+
+    while (!Refs.empty()) {
+      MachineInstr *LastUDMI = Refs.back().first;
+      Refs.pop_back();
+
       MachineOperand *LastUD = NULL;
       for (unsigned i = 0, e = LastUDMI->getNumOperands(); i != e; ++i) {
         MachineOperand &MO = LastUDMI->getOperand(i);
@@ -1339,14 +1353,24 @@
         if (!LastUD || (LastUD->isUse() && MO.isDef()))
           LastUD = &MO;
         if (LastUDMI->isRegTiedToDefOperand(i))
-          return;
+          break;
       }
-      if (LastUD->isDef())
-        LastUD->setIsDead();
-      else {
+      if (LastUD->isDef()) {
+        // If the instruction has no side effect, delete it and propagate
+        // backward further. Otherwise, mark is dead and we are done.
+        const TargetInstrDesc &TID = LastUDMI->getDesc();
+        if (TID.mayStore() || TID.isCall() || TID.isTerminator() ||
+            TID.hasUnmodeledSideEffects()) {
+          LastUD->setIsDead();
+          break;
+        }
+        VRM.RemoveMachineInstrFromMaps(LastUDMI);
+        MBB->erase(LastUDMI);
+      } else {
         LastUD->setIsKill();
         RegKills.set(Reg);
         KillOps[Reg] = LastUD;
+        break;
       }
     }
   }
@@ -2027,7 +2051,7 @@
                      TRI->isSubRegister(KillRegs[0], Dst) ||
                      TRI->isSuperRegister(KillRegs[0], Dst));
               // Last def is now dead.
-              TransferDeadness(&MBB, Dist, Src, RegKills, KillOps);
+              TransferDeadness(&MBB, Dist, Src, RegKills, KillOps, VRM);
             }
             VRM.RemoveMachineInstrFromMaps(&MI);
             MBB.erase(&MI);

Modified: llvm/trunk/test/CodeGen/X86/2007-03-01-SpillerCrash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-03-01-SpillerCrash.ll?rev=71606&r1=71605&r2=71606&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/X86/2007-03-01-SpillerCrash.ll (original)
+++ llvm/trunk/test/CodeGen/X86/2007-03-01-SpillerCrash.ll Tue May 12 18:07:00 2009
@@ -1,4 +1,5 @@
 ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin8 -mattr=+sse2
+; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin8 -mattr=+sse2 | not grep movhlps
 
 define void @test() nounwind {
 test.exit:





More information about the llvm-commits mailing list