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

Andrew Trick atrick at apple.com
Tue Feb 8 09:39:46 PST 2011


Author: atrick
Date: Tue Feb  8 11:39:46 2011
New Revision: 125089

URL: http://llvm.org/viewvc/llvm-project?rev=125089&view=rev
Log:
Fix PostRA antidependence breaker.

Avoid using the same register for two def operands or and earlyclobber
def and use operand. This fixes PR8986 and improves on the prior fix
for rdar://problem/8959122.

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=125089&r1=125088&r2=125089&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp (original)
+++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp Tue Feb  8 11:39:46 2011
@@ -325,17 +325,55 @@
   }
 }
 
-// Check all machine instructions that define the antidependent register.
-// Return true if any of these instructions define the new register.
+// Check all machine operands that reference the antidependent register and must
+// be replaced by NewReg. Return true if any of their parent instructions may
+// clobber the new register.
+//
+// Note: AntiDepReg may be referenced by a two-address instruction such that
+// it's use operand is tied to a def operand. We guard against the case in which
+// the two-address instruction also defines NewReg, as may happen with
+// pre/postincrement loads. In this case, both the use and def operands are in
+// RegRefs because the def is inserted by PrescanInstruction and not erased
+// during ScanInstruction. So checking for an instructions with definitions of
+// both NewReg and AntiDepReg covers it.
 bool
-CriticalAntiDepBreaker::isNewRegModifiedByRefs(RegRefIter RegRefBegin,
-                                               RegRefIter RegRefEnd,
-                                               unsigned NewReg)
+CriticalAntiDepBreaker::isNewRegClobberedByRefs(RegRefIter RegRefBegin,
+                                                RegRefIter RegRefEnd,
+                                                unsigned NewReg)
 {
   for (RegRefIter I = RegRefBegin; I != RegRefEnd; ++I ) {
-    MachineOperand *MO = I->second;
-    if (MO->getParent()->modifiesRegister(NewReg, TRI))
+    MachineOperand *RefOper = I->second;
+
+    // Don't allow the instruction defining AntiDepReg to earlyclobber its
+    // operands, in case they may be assigned to NewReg. In this case antidep
+    // breaking must fail, but it's too rare to bother optimizing.
+    if (RefOper->isDef() && RefOper->isEarlyClobber())
       return true;
+
+    // Handle cases in which this instructions defines NewReg.
+    MachineInstr *MI = RefOper->getParent();
+    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+      const MachineOperand &CheckOper = MI->getOperand(i);
+
+      if (!CheckOper.isReg() || !CheckOper.isDef() ||
+          CheckOper.getReg() != NewReg)
+        continue;
+
+      // Don't allow the instruction to define NewReg and AntiDepReg.
+      // When AntiDepReg is renamed it will be an illegal op.
+      if (RefOper->isDef())
+        return true;
+
+      // Don't allow an instruction using AntiDepReg to be earlyclobbered by
+      // NewReg
+      if (CheckOper.isEarlyClobber())
+        return true;
+
+      // Don't allow inline asm to define NewReg at all. Who know what it's
+      // doing with it.
+      if (MI->isInlineAsm())
+        return true;
+    }
   }
   return false;
 }
@@ -361,7 +399,7 @@
     // 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 (isNewRegClobberedByRefs(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))

Modified: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=125089&r1=125088&r2=125089&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h (original)
+++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Tue Feb  8 11:39:46 2011
@@ -92,9 +92,9 @@
   private:
     void PrescanInstruction(MachineInstr *MI);
     void ScanInstruction(MachineInstr *MI, unsigned Count);
-    bool isNewRegModifiedByRefs(RegRefIter RegRefBegin,
-                                RegRefIter RegRefEnd,
-                                unsigned NewReg);
+    bool isNewRegClobberedByRefs(RegRefIter RegRefBegin,
+                                 RegRefIter RegRefEnd,
+                                 unsigned NewReg);
     unsigned findSuitableFreeRegister(RegRefIter RegRefBegin,
                                       RegRefIter RegRefEnd,
                                       unsigned AntiDepReg,





More information about the llvm-commits mailing list