[llvm-branch-commits] [llvm-branch] r70394 - in /llvm/branches/Apple/Dib: include/llvm/Target/TargetRegisterInfo.h lib/CodeGen/LiveInterval.cpp lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/RegAllocLinearScan.cpp lib/CodeGen/SimpleRegisterCoalescing.cpp lib/CodeGen/TwoAddressInstructionPass.cpp test/CodeGen/X86/2009-04-27-LiveIntervalsAssert.ll test/CodeGen/X86/2009-04-27-LiveIntervalsAssert2.ll test/CodeGen/X86/2009-04-27-LiveIntervalsBug.ll

Bill Wendling isanbard at gmail.com
Wed Apr 29 11:39:26 PDT 2009


Author: void
Date: Wed Apr 29 13:39:25 2009
New Revision: 70394

URL: http://llvm.org/viewvc/llvm-project?rev=70394&view=rev
Log:
--- Merging r70212 into '.':
U    lib/CodeGen/LiveInterval.cpp
--- Merging r70213 into '.':
A    test/CodeGen/X86/2009-04-27-LiveIntervalsAssert.ll
U    lib/CodeGen/LiveIntervalAnalysis.cpp
--- Merging r70245 into '.':
A    test/CodeGen/X86/2009-04-27-LiveIntervalsBug.ll
G    lib/CodeGen/LiveIntervalAnalysis.cpp
--- Merging r70279 into '.':
A    test/CodeGen/X86/2009-04-27-LiveIntervalsAssert2.ll
U    lib/CodeGen/TwoAddressInstructionPass.cpp
--- Merging r70291 into '.':
A    test/CodeGen/X86/2009-04-27-CoalescerAssert.ll
--- Merging r70309 into '.':
U    include/llvm/Target/TargetRegisterInfo.h
U    lib/CodeGen/SimpleRegisterCoalescing.cpp
--- Merging r70351 into '.':
U    lib/CodeGen/RegAllocLinearScan.cpp


Added:
    llvm/branches/Apple/Dib/test/CodeGen/X86/2009-04-27-LiveIntervalsAssert.ll
      - copied unchanged from r70213, llvm/trunk/test/CodeGen/X86/2009-04-27-LiveIntervalsAssert.ll
    llvm/branches/Apple/Dib/test/CodeGen/X86/2009-04-27-LiveIntervalsAssert2.ll
      - copied unchanged from r70279, llvm/trunk/test/CodeGen/X86/2009-04-27-LiveIntervalsAssert2.ll
    llvm/branches/Apple/Dib/test/CodeGen/X86/2009-04-27-LiveIntervalsBug.ll
      - copied unchanged from r70245, llvm/trunk/test/CodeGen/X86/2009-04-27-LiveIntervalsBug.ll
Modified:
    llvm/branches/Apple/Dib/include/llvm/Target/TargetRegisterInfo.h
    llvm/branches/Apple/Dib/lib/CodeGen/LiveInterval.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLinearScan.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/SimpleRegisterCoalescing.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp

Modified: llvm/branches/Apple/Dib/include/llvm/Target/TargetRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/Target/TargetRegisterInfo.h?rev=70394&r1=70393&r2=70394&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/Target/TargetRegisterInfo.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/Target/TargetRegisterInfo.h Wed Apr 29 13:39:25 2009
@@ -466,6 +466,16 @@
   /// exist.
   virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0;
 
+  /// getMatchingSuperReg - Return a super-register of the specified register
+  /// Reg so its sub-register of index SubIdx is Reg.
+  unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, 
+                               const TargetRegisterClass *RC) const {
+    for (const unsigned *SRs = getSuperRegisters(Reg); unsigned SR = *SRs;++SRs)
+      if (Reg == getSubReg(SR, SubIdx) && RC->contains(SR))
+        return SR;
+    return 0;
+  }
+
   //===--------------------------------------------------------------------===//
   // Register Class Information
   //

Modified: llvm/branches/Apple/Dib/lib/CodeGen/LiveInterval.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/LiveInterval.cpp?rev=70394&r1=70393&r2=70394&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/LiveInterval.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/LiveInterval.cpp Wed Apr 29 13:39:25 2009
@@ -629,6 +629,12 @@
       UnusedValNo = 0;
     }
   }
+
+  if (UnusedValNo) {
+    // Delete the last unused val#.
+    valnos.pop_back();
+    UnusedValNo->~VNInfo();
+  }
 }
 
 void LiveInterval::MergeInClobberRange(unsigned Start, unsigned End,

Modified: llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=70394&r1=70393&r2=70394&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Apr 29 13:39:25 2009
@@ -612,14 +612,24 @@
       DOUT << " killed";
       end = getUseIndex(baseIndex) + 1;
       goto exit;
-    } else if (mi->modifiesRegister(interval.reg, tri_)) {
-      // Another instruction redefines the register before it is ever read.
-      // Then the register is essentially dead at the instruction that defines
-      // it. Hence its interval is:
-      // [defSlot(def), defSlot(def)+1)
-      DOUT << " dead";
-      end = start + 1;
-      goto exit;
+    } else {
+      int DefIdx = mi->findRegisterDefOperandIdx(interval.reg, false, tri_);
+      if (DefIdx != -1) {
+        if (mi->isRegTiedToUseOperand(DefIdx)) {
+          // Two-address instruction.
+          end = getDefIndex(baseIndex);
+          if (mi->getOperand(DefIdx).isEarlyClobber())
+            end = getUseIndex(baseIndex);
+        } else {
+          // Another instruction redefines the register before it is ever read.
+          // Then the register is essentially dead at the instruction that defines
+          // it. Hence its interval is:
+          // [defSlot(def), defSlot(def)+1)
+          DOUT << " dead";
+          end = start + 1;
+        }
+        goto exit;
+      }
     }
     
     baseIndex += InstrSlots::NUM;
@@ -627,8 +637,8 @@
   
   // The only case we should have a dead physreg here without a killing or
   // instruction where we know it's dead is if it is live-in to the function
-  // and never used.
-  assert(!CopyMI && "physreg was not killed in defining block!");
+  // and never used. Another possible case is the implicit use of the
+  // physical register has been deleted by two-address pass.
   end = start + 1;
 
 exit:
@@ -663,14 +673,14 @@
         MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG ||
         tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
       CopyMI = MI;
-    handlePhysicalRegisterDef(MBB, MI, MIIdx, MO, 
+    handlePhysicalRegisterDef(MBB, MI, MIIdx, MO,
                               getOrCreateInterval(MO.getReg()), CopyMI);
     // Def of a register also defines its sub-registers.
     for (const unsigned* AS = tri_->getSubRegisters(MO.getReg()); *AS; ++AS)
       // If MI also modifies the sub-register explicitly, avoid processing it
       // more than once. Do not pass in TRI here so it checks for exact match.
       if (!MI->modifiesRegister(*AS))
-        handlePhysicalRegisterDef(MBB, MI, MIIdx, MO, 
+        handlePhysicalRegisterDef(MBB, MI, MIIdx, MO,
                                   getOrCreateInterval(*AS), 0);
   }
 }

Modified: llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLinearScan.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLinearScan.cpp?rev=70394&r1=70393&r2=70394&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLinearScan.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLinearScan.cpp Wed Apr 29 13:39:25 2009
@@ -799,8 +799,14 @@
           Reg = SrcReg;
         else if (vrm_->isAssignedReg(SrcReg))
           Reg = vrm_->getPhys(SrcReg);
-        if (Reg && allocatableRegs_[Reg] && RC->contains(Reg))
-          cur->preference = Reg;
+        if (Reg) {
+          if (SrcSubReg)
+            Reg = tri_->getSubReg(Reg, SrcSubReg);
+          if (DstSubReg)
+            Reg = tri_->getMatchingSuperReg(Reg, DstSubReg, RC);
+          if (Reg && allocatableRegs_[Reg] && RC->contains(Reg))
+            cur->preference = Reg;
+        }
       }
     }
   }
@@ -1265,14 +1271,10 @@
   // If copy coalescer has assigned a "preferred" register, check if it's
   // available first.
   if (cur->preference) {
+    DOUT << "(preferred: " << tri_->getName(cur->preference) << ") ";
     if (prt_->isRegAvail(cur->preference) && 
-        RC->contains(cur->preference)) {
-      DOUT << "\t\tassigned the preferred register: "
-           << tri_->getName(cur->preference) << "\n";
+        RC->contains(cur->preference))
       return cur->preference;
-    } else
-      DOUT << "\t\tunable to assign the preferred register: "
-           << tri_->getName(cur->preference) << "\n";
   }
 
   if (!DowngradedRegs.empty()) {

Modified: llvm/branches/Apple/Dib/lib/CodeGen/SimpleRegisterCoalescing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=70394&r1=70393&r2=70394&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SimpleRegisterCoalescing.cpp Wed Apr 29 13:39:25 2009
@@ -1002,18 +1002,6 @@
   }
 }
 
-/// getMatchingSuperReg - Return a super-register of the specified register
-/// Reg so its sub-register of index SubIdx is Reg.
-static unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, 
-                                    const TargetRegisterClass *RC,
-                                    const TargetRegisterInfo* TRI) {
-  for (const unsigned *SRs = TRI->getSuperRegisters(Reg);
-       unsigned SR = *SRs; ++SRs)
-    if (Reg == TRI->getSubReg(SR, SubIdx) && RC->contains(SR))
-      return SR;
-  return 0;
-}
-
 /// isWinToJoinCrossClass - Return true if it's profitable to coalesce
 /// two virtual registers from different register classes.
 bool
@@ -1066,7 +1054,7 @@
           TargetRegisterInfo::isPhysicalRegister(SrcReg)
           ? tri_->getPhysicalRegisterRegClass(SrcReg)
           : mri_->getRegClass(SrcReg);
-        if (!getMatchingSuperReg(PhysReg, SubIdx, RC, tri_))
+        if (!tri_->getMatchingSuperReg(PhysReg, SubIdx, RC))
           return true;
       }
     }
@@ -1082,7 +1070,7 @@
           TargetRegisterInfo::isPhysicalRegister(DstReg)
           ? tri_->getPhysicalRegisterRegClass(DstReg)
           : mri_->getRegClass(DstReg);
-        if (!getMatchingSuperReg(PhysReg, SubIdx, RC, tri_))
+        if (!tri_->getMatchingSuperReg(PhysReg, SubIdx, RC))
           return true;
       }
     }
@@ -1099,7 +1087,7 @@
                                                unsigned SrcReg, unsigned SubIdx,
                                                unsigned &RealDstReg) {
   const TargetRegisterClass *RC = mri_->getRegClass(SrcReg);
-  RealDstReg = getMatchingSuperReg(DstReg, SubIdx, RC, tri_);
+  RealDstReg = tri_->getMatchingSuperReg(DstReg, SubIdx, RC);
   assert(RealDstReg && "Invalid extract_subreg instruction!");
 
   // For this type of EXTRACT_SUBREG, conservatively
@@ -1129,7 +1117,7 @@
                                                unsigned SrcReg, unsigned SubIdx,
                                                unsigned &RealSrcReg) {
   const TargetRegisterClass *RC = mri_->getRegClass(DstReg);
-  RealSrcReg = getMatchingSuperReg(SrcReg, SubIdx, RC, tri_);
+  RealSrcReg = tri_->getMatchingSuperReg(SrcReg, SubIdx, RC);
   assert(RealSrcReg && "Invalid extract_subreg instruction!");
 
   LiveInterval &RHS = li_->getInterval(DstReg);

Modified: llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=70394&r1=70393&r2=70394&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp Wed Apr 29 13:39:25 2009
@@ -88,6 +88,9 @@
     bool NoUseAfterLastDef(unsigned Reg, MachineBasicBlock *MBB, unsigned Dist,
                            unsigned &LastDef);
 
+    MachineInstr *FindLastUseInMBB(unsigned Reg, MachineBasicBlock *MBB,
+                                   unsigned Dist);
+
     bool isProfitableToCommute(unsigned regB, unsigned regC,
                                MachineInstr *MI, MachineBasicBlock *MBB,
                                unsigned Dist);
@@ -310,6 +313,28 @@
   return !(LastUse > LastDef && LastUse < Dist);
 }
 
+MachineInstr *TwoAddressInstructionPass::FindLastUseInMBB(unsigned Reg,
+                                                         MachineBasicBlock *MBB,
+                                                         unsigned Dist) {
+  unsigned LastUseDist = Dist;
+  MachineInstr *LastUse = 0;
+  for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(Reg),
+         E = MRI->reg_end(); I != E; ++I) {
+    MachineOperand &MO = I.getOperand();
+    MachineInstr *MI = MO.getParent();
+    if (MI->getParent() != MBB)
+      continue;
+    DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(MI);
+    if (DI == DistanceMap.end())
+      continue;
+    if (MO.isUse() && DI->second < LastUseDist) {
+      LastUse = DI->first;
+      LastUseDist = DI->second;
+    }
+  }
+  return LastUse;
+}
+
 /// isCopyToReg - Return true if the specified MI is a copy instruction or
 /// a extract_subreg instruction. It also returns the source and destination
 /// registers and whether they are physical registers by reference.
@@ -684,7 +709,9 @@
 
 /// isSafeToDelete - If the specified instruction does not produce any side
 /// effects and all of its defs are dead, then it's safe to delete.
-static bool isSafeToDelete(MachineInstr *MI, const TargetInstrInfo *TII) {
+static bool isSafeToDelete(MachineInstr *MI, unsigned Reg,
+                           const TargetInstrInfo *TII,
+                           SmallVector<unsigned, 4> &Kills) {
   const TargetInstrDesc &TID = MI->getDesc();
   if (TID.mayStore() || TID.isCall())
     return false;
@@ -693,10 +720,12 @@
 
   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
     MachineOperand &MO = MI->getOperand(i);
-    if (!MO.isReg() || !MO.isDef())
+    if (!MO.isReg())
       continue;
-    if (!MO.isDead())
+    if (MO.isDef() && !MO.isDead())
       return false;
+    if (MO.isUse() && MO.getReg() != Reg && MO.isKill())
+      Kills.push_back(MO.getReg());
   }
 
   return true;
@@ -787,11 +816,53 @@
           if (!isKilled(*mi, regB, MRI, TII)) {
             // If regA is dead and the instruction can be deleted, just delete
             // it so it doesn't clobber regB.
-            if (mi->getOperand(ti).isDead() && isSafeToDelete(mi, TII)) {
-              mbbi->erase(mi); // Nuke the old inst.
-              mi = nmi;
-              ++NumDeletes;
-              break; // Done with this instruction.
+            SmallVector<unsigned, 4> Kills;
+            if (mi->getOperand(ti).isDead() &&
+                isSafeToDelete(mi, regB, TII, Kills)) {
+              SmallVector<std::pair<std::pair<unsigned, bool>
+                ,MachineInstr*>, 4> NewKills;
+              bool ReallySafe = true;
+              // If this instruction kills some virtual registers, we need
+              // update the kill information. If it's not possible to do so,
+              // then bail out.
+              while (!Kills.empty()) {
+                unsigned Kill = Kills.back();
+                Kills.pop_back();
+                if (TargetRegisterInfo::isPhysicalRegister(Kill)) {
+                  ReallySafe = false;
+                  break;
+                }
+                MachineInstr *LastKill = FindLastUseInMBB(Kill, &*mbbi, Dist);
+                if (LastKill) {
+                  bool isModRef = LastKill->modifiesRegister(Kill);
+                  NewKills.push_back(std::make_pair(std::make_pair(Kill,isModRef),
+                                                    LastKill));
+                } else {
+                  ReallySafe = false;
+                  break;
+                }
+              }
+
+              if (ReallySafe) {
+                if (LV) {
+                  while (!NewKills.empty()) {
+                    MachineInstr *NewKill = NewKills.back().second;
+                    unsigned Kill = NewKills.back().first.first;
+                    bool isDead = NewKills.back().first.second;
+                    NewKills.pop_back();
+                    if (LV->removeVirtualRegisterKilled(Kill,  mi)) {
+                      if (isDead)
+                        LV->addVirtualRegisterDead(Kill, NewKill);
+                      else
+                        LV->addVirtualRegisterKilled(Kill, NewKill);
+                    }
+                  }
+                }
+                mbbi->erase(mi); // Nuke the old inst.
+                mi = nmi;
+                ++NumDeletes;
+                break; // Done with this instruction.
+              }
             }
 
             // If this instruction is commutative, check to see if C dies.  If





More information about the llvm-branch-commits mailing list