[llvm-branch-commits] [llvm-branch] r90505 - in /llvm/branches/Apple/Zoidberg: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/RegAllocLinearScan.cpp test/CodeGen/X86/2009-01-12-CoalescerBug.ll test/CodeGen/X86/twoaddr-coalesce.ll

Jakob Stoklund Olesen stoklund at 2pi.dk
Thu Dec 3 16:44:58 PST 2009


Author: stoklund
Date: Thu Dec  3 18:44:58 2009
New Revision: 90505

URL: http://llvm.org/viewvc/llvm-project?rev=90505&view=rev
Log:
Merge 90481 90502

Modified:
    llvm/branches/Apple/Zoidberg/include/llvm/CodeGen/LiveIntervalAnalysis.h
    llvm/branches/Apple/Zoidberg/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/branches/Apple/Zoidberg/lib/CodeGen/RegAllocLinearScan.cpp
    llvm/branches/Apple/Zoidberg/test/CodeGen/X86/2009-01-12-CoalescerBug.ll
    llvm/branches/Apple/Zoidberg/test/CodeGen/X86/twoaddr-coalesce.ll

Modified: llvm/branches/Apple/Zoidberg/include/llvm/CodeGen/LiveIntervalAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Zoidberg/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=90505&r1=90504&r2=90505&view=diff

==============================================================================
--- llvm/branches/Apple/Zoidberg/include/llvm/CodeGen/LiveIntervalAnalysis.h (original)
+++ llvm/branches/Apple/Zoidberg/include/llvm/CodeGen/LiveIntervalAnalysis.h Thu Dec  3 18:44:58 2009
@@ -117,6 +117,12 @@
     bool conflictsWithPhysRegDef(const LiveInterval &li, VirtRegMap &vrm,
                                  unsigned reg);
 
+    /// conflictsWithPhysRegUse - Returns true if the specified register is used
+    /// or defined during the duration of the specified interval. Copies to and
+    /// from li.reg are allowed.
+    bool conflictsWithPhysRegUse(const LiveInterval &li, VirtRegMap &vrm,
+                                 unsigned reg);
+
     /// conflictsWithPhysRegRef - Similar to conflictsWithPhysRegRef except
     /// it can check use as well.
     bool conflictsWithPhysRegRef(LiveInterval &li, unsigned Reg,

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

==============================================================================
--- llvm/branches/Apple/Zoidberg/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/branches/Apple/Zoidberg/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Dec  3 18:44:58 2009
@@ -157,21 +157,15 @@
          I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) {
     for (SlotIndex index = I->start.getBaseIndex(),
            end = I->end.getPrevSlot().getBaseIndex().getNextIndex();
-           index != end;
-           index = index.getNextIndex()) {
-      // skip deleted instructions
-      while (index != end && !getInstructionFromIndex(index))
-        index = index.getNextIndex();
-      if (index == end) break;
-
+         index != end;
+         index = index.getNextIndex()) {
       MachineInstr *MI = getInstructionFromIndex(index);
-      unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
-      if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
-        if (SrcReg == li.reg || DstReg == li.reg)
-          continue;
+      if (!MI)
+        continue;               // skip deleted instructions
+
       for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
         MachineOperand& mop = MI->getOperand(i);
-        if (!mop.isReg())
+        if (!mop.isReg() || mop.isUse())
           continue;
         unsigned PhysReg = mop.getReg();
         if (PhysReg == 0 || PhysReg == li.reg)
@@ -190,6 +184,50 @@
   return false;
 }
 
+/// conflictsWithPhysRegUse - Returns true if the specified register is used or
+/// defined during the duration of the specified interval. Copies to and from
+/// li.reg are allowed.
+bool LiveIntervals::conflictsWithPhysRegUse(const LiveInterval &li,
+                                            VirtRegMap &vrm, unsigned reg) {
+  for (LiveInterval::Ranges::const_iterator
+         I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) {
+    for (SlotIndex index = I->start.getBaseIndex(),
+           end = I->end.getPrevSlot().getBaseIndex().getNextIndex();
+         index != end;
+         index = index.getNextIndex()) {
+      MachineInstr *MI = getInstructionFromIndex(index);
+      if (!MI)
+        continue;               // skip deleted instructions
+
+      // Terminators are considered conflicts since reg may be used at the
+      // destination.
+      if (MI->getDesc().isTerminator())
+        return true;
+
+      for (unsigned i = 0, e = MI->getNumOperands(); i != e;  ++i) {
+        MachineOperand& mop = MI->getOperand(i);
+        if (!mop.isReg() || mop.isUndef())
+          continue;
+        unsigned PhysReg = mop.getReg();
+        if (PhysReg == 0 || PhysReg == li.reg)
+          continue;
+        if (TargetRegisterInfo::isVirtualRegister(PhysReg)) {
+          if (!vrm.hasPhys(PhysReg))
+            continue;
+          PhysReg = vrm.getPhys(PhysReg);
+        }
+        if (PhysReg && tri_->regsOverlap(PhysReg, reg)) {
+          unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+          if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) ||
+              (SrcReg != li.reg && DstReg != li.reg))
+            return true;
+        }
+      }
+    }
+  }
+  return false;
+}
+
 /// conflictsWithPhysRegRef - Similar to conflictsWithPhysRegRef except
 /// it can check use as well.
 bool LiveIntervals::conflictsWithPhysRegRef(LiveInterval &li,
@@ -201,15 +239,9 @@
            end = I->end.getPrevSlot().getBaseIndex().getNextIndex();
            index != end;
            index = index.getNextIndex()) {
-      // Skip deleted instructions.
-      MachineInstr *MI = 0;
-      while (index != end) {
-        MI = getInstructionFromIndex(index);
-        if (MI)
-          break;
-        index = index.getNextIndex();
-      }
-      if (index == end) break;
+      MachineInstr *MI = getInstructionFromIndex(index);
+      if (!MI)
+        continue;               // skip deleted instructions
 
       if (JoinedCopies.count(MI))
         continue;

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

==============================================================================
--- llvm/branches/Apple/Zoidberg/lib/CodeGen/RegAllocLinearScan.cpp (original)
+++ llvm/branches/Apple/Zoidberg/lib/CodeGen/RegAllocLinearScan.cpp Thu Dec  3 18:44:58 2009
@@ -387,66 +387,70 @@
         RelatedRegClasses.unionSets(I->second, OneClassForEachPhysReg[*AS]);
 }
 
-/// attemptTrivialCoalescing - If a simple interval is defined by a copy,
-/// try allocate the definition the same register as the source register
-/// if the register is not defined during live time of the interval. This
-/// eliminate a copy. This is used to coalesce copies which were not
-/// coalesced away before allocation either due to dest and src being in
-/// different register classes or because the coalescer was overly
-/// conservative.
+/// attemptTrivialCoalescing - If a simple interval is defined by a copy, try
+/// allocate the definition the same register as the source register if the
+/// register is not defined during live time of the interval. If the interval is
+/// killed by a copy, try to use the destination register. This eliminates a
+/// copy. This is used to coalesce copies which were not coalesced away before
+/// allocation either due to dest and src being in different register classes or
+/// because the coalescer was overly conservative.
 unsigned RALinScan::attemptTrivialCoalescing(LiveInterval &cur, unsigned Reg) {
   unsigned Preference = vrm_->getRegAllocPref(cur.reg);
   if ((Preference && Preference == Reg) || !cur.containsOneValue())
     return Reg;
 
   VNInfo *vni = cur.begin()->valno;
-  if ((vni->def == SlotIndex()) ||
-      vni->isUnused() || !vni->isDefAccurate())
+  if (vni->isUnused())
     return Reg;
-  MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
-  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))
+  unsigned CandReg;
+  bool forward;                 // extending physreg forward
+  {
+    MachineInstr *CopyMI;
+    unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+    if (vni->def != SlotIndex() && vni->isDefAccurate() &&
+        (CopyMI = li_->getInstructionFromIndex(vni->def)) &&
+        tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg))
+      // Defined by a copy, try to extend SrcReg forward
+      CandReg = SrcReg, forward = true;
+    else if (cur.ranges.size()==1 &&
+             (CopyMI =
+              li_->getInstructionFromIndex(cur.begin()->end.getBaseIndex())) &&
+             tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
+             cur.reg == SrcReg)
+      // Only used by a copy, try to extend DstReg backwards
+      CandReg = DstReg, forward = false;
+    else
+      return Reg;
+  }
+
+  if (TargetRegisterInfo::isVirtualRegister(CandReg)) {
+    if (!vrm_->isAssignedReg(CandReg))
       return Reg;
-    PhysReg = vrm_->getPhys(SrcReg);
+    CandReg = vrm_->getPhys(CandReg);
   }
-  if (Reg == PhysReg)
+  if (Reg == CandReg)
     return Reg;
 
   const TargetRegisterClass *RC = mri_->getRegClass(cur.reg);
-  if (!RC->contains(PhysReg))
+  if (!RC->contains(CandReg))
     return Reg;
 
-  // Try to coalesce.
-  if (!li_->conflictsWithPhysRegDef(cur, *vrm_, PhysReg)) {
-    DEBUG(errs() << "Coalescing: " << cur << " -> " << tri_->getName(PhysReg)
-                 << '\n');
-    vrm_->clearVirt(cur.reg);
-    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::use_iterator I = mri_->use_begin(cur.reg),
-             E = mri_->use_end(); I != E; ++I) {
-        MachineOperand &O = I.getOperand();
-        if (!O.isKill())
-          continue;
-        MachineInstr *MI = &*I;
-        if (SrcLI.liveAt(li_->getInstructionIndex(MI).getDefIndex()))
-          O.setIsKill(false);
-      }
-    }
-
-    ++NumCoalesce;
-    return PhysReg;
+  if (forward) {
+    if (li_->conflictsWithPhysRegDef(cur, *vrm_, CandReg))
+      return Reg;
+  } else {
+    if (li_->conflictsWithPhysRegUse(cur, *vrm_, CandReg))
+      return Reg;
   }
 
-  return Reg;
+  // Try to coalesce.
+  DEBUG(errs() << "Coalescing: " << cur << " -> " << tri_->getName(CandReg)
+        << '\n');
+  vrm_->clearVirt(cur.reg);
+  vrm_->assignVirt2Phys(cur.reg, CandReg);
+
+  ++NumCoalesce;
+  return CandReg;
 }
 
 bool RALinScan::runOnMachineFunction(MachineFunction &fn) {

Modified: llvm/branches/Apple/Zoidberg/test/CodeGen/X86/2009-01-12-CoalescerBug.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Zoidberg/test/CodeGen/X86/2009-01-12-CoalescerBug.ll?rev=90505&r1=90504&r2=90505&view=diff

==============================================================================
--- llvm/branches/Apple/Zoidberg/test/CodeGen/X86/2009-01-12-CoalescerBug.ll (original)
+++ llvm/branches/Apple/Zoidberg/test/CodeGen/X86/2009-01-12-CoalescerBug.ll Thu Dec  3 18:44:58 2009
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | grep movq | count 2
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | grep movq | count 1
 ; PR3311
 
 	%struct.CUMULATIVE_ARGS = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }

Modified: llvm/branches/Apple/Zoidberg/test/CodeGen/X86/twoaddr-coalesce.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Zoidberg/test/CodeGen/X86/twoaddr-coalesce.ll?rev=90505&r1=90504&r2=90505&view=diff

==============================================================================
--- llvm/branches/Apple/Zoidberg/test/CodeGen/X86/twoaddr-coalesce.ll (original)
+++ llvm/branches/Apple/Zoidberg/test/CodeGen/X86/twoaddr-coalesce.ll Thu Dec  3 18:44:58 2009
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=x86 | grep mov | count 5
+; RUN: llc < %s -march=x86 | grep mov | count 4
 ; rdar://6523745
 
 @"\01LC" = internal constant [4 x i8] c"%d\0A\00"		; <[4 x i8]*> [#uses=1]





More information about the llvm-branch-commits mailing list