[llvm-commits] [llvm] r118032 - in /llvm/trunk/lib/CodeGen: CriticalAntiDepBreaker.cpp CriticalAntiDepBreaker.h

Andrew Trick atrick at apple.com
Tue Nov 2 11:16:45 PDT 2010


Author: atrick
Date: Tue Nov  2 13:16:45 2010
New Revision: 118032

URL: http://llvm.org/viewvc/llvm-project?rev=118032&view=rev
Log:
Fixes <rdar://problem/8612856>: During postRAsched, the antidependence
breaker needs to check all definitions of the antidepenent register to
avoid multiple defs of the same new register.

Modified:
    llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp
    llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h

Modified: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp?rev=118032&r1=118031&r2=118032&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp (original)
+++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp Tue Nov  2 13:16:45 2010
@@ -325,8 +325,25 @@
   }
 }
 
+// Check all machine instructions that define the antidependent register.
+// Return true if any of these instructions define the new register.
+bool
+CriticalAntiDepBreaker::isNewRegModifiedByRefs(RegRefIter RegRefBegin,
+                                               RegRefIter RegRefEnd,
+                                               unsigned NewReg)
+{
+  for (RegRefIter I = RegRefBegin; I != RegRefEnd; ++I ) {
+    MachineOperand *MO = I->second;
+    if (MO->isDef()) continue;
+    if (MO->getParent()->modifiesRegister(NewReg, TRI))
+      return true;
+  }
+  return false;
+}
+
 unsigned
-CriticalAntiDepBreaker::findSuitableFreeRegister(MachineInstr *MI,
+CriticalAntiDepBreaker::findSuitableFreeRegister(RegRefIter RegRefBegin,
+                                                 RegRefIter RegRefEnd,
                                                  unsigned AntiDepReg,
                                                  unsigned LastNewReg,
                                                  const TargetRegisterClass *RC)
@@ -342,10 +359,10 @@
     // an anti-dependence with this AntiDepReg, because that would
     // re-introduce that anti-dependence.
     if (NewReg == LastNewReg) continue;
-    // If the instruction already has a def of the NewReg, it's not suitable.
-    // For example, Instruction with multiple definitions can result in this
-    // condition.
-    if (MI->modifiesRegister(NewReg, TRI)) continue;
+    // If any instructions that define AntiDepReg also define the NewReg, it's
+    // not suitable.  For example, Instruction with multiple definitions can
+    // result in this condition.
+    if (isNewRegModifiedByRefs(RegRefBegin, RegRefEnd, NewReg)) continue;
     // If NewReg is dead and NewReg's most recent def is not before
     // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg.
     assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u))
@@ -552,7 +569,11 @@
     // TODO: Instead of picking the first free register, consider which might
     // be the best.
     if (AntiDepReg != 0) {
-      if (unsigned NewReg = findSuitableFreeRegister(MI, AntiDepReg,
+      std::pair<std::multimap<unsigned, MachineOperand *>::iterator,
+                std::multimap<unsigned, MachineOperand *>::iterator>
+        Range = RegRefs.equal_range(AntiDepReg);
+      if (unsigned NewReg = findSuitableFreeRegister(Range.first, Range.second,
+                                                     AntiDepReg,
                                                      LastNewReg[AntiDepReg],
                                                      RC)) {
         DEBUG(dbgs() << "Breaking anti-dependence edge on "
@@ -562,9 +583,6 @@
 
         // Update the references to the old register to refer to the new
         // register.
-        std::pair<std::multimap<unsigned, MachineOperand *>::iterator,
-                  std::multimap<unsigned, MachineOperand *>::iterator>
-           Range = RegRefs.equal_range(AntiDepReg);
         for (std::multimap<unsigned, MachineOperand *>::iterator
              Q = Range.first, QE = Range.second; Q != QE; ++Q) {
           Q->second->setReg(NewReg);

Modified: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=118032&r1=118031&r2=118032&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h (original)
+++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Tue Nov  2 13:16:45 2010
@@ -50,6 +50,8 @@
 
     /// RegRegs - Map registers to all their references within a live range.
     std::multimap<unsigned, MachineOperand *> RegRefs;
+    typedef std::multimap<unsigned, MachineOperand *>::const_iterator
+      RegRefIter;
 
     /// KillIndices - The index of the most recent kill (proceding bottom-up),
     /// or ~0u if the register is not live.
@@ -90,10 +92,14 @@
   private:
     void PrescanInstruction(MachineInstr *MI);
     void ScanInstruction(MachineInstr *MI, unsigned Count);
-    unsigned findSuitableFreeRegister(MachineInstr *MI,
+    bool isNewRegModifiedByRefs(RegRefIter RegRefBegin,
+                                RegRefIter RegRefEnd,
+                                unsigned NewReg);
+    unsigned findSuitableFreeRegister(RegRefIter RegRefBegin,
+                                      RegRefIter RegRefEnd,
                                       unsigned AntiDepReg,
                                       unsigned LastNewReg,
-                                      const TargetRegisterClass *);
+                                      const TargetRegisterClass *RC);
   };
 }
 





More information about the llvm-commits mailing list