[llvm-commits] [llvm] r122472 - in /llvm/trunk: lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp test/CodeGen/Generic/add-with-overflow-128.ll

Andrew Trick atrick at apple.com
Wed Dec 22 19:15:51 PST 2010


Author: atrick
Date: Wed Dec 22 21:15:51 2010
New Revision: 122472

URL: http://llvm.org/viewvc/llvm-project?rev=122472&view=rev
Log:
Fixes PR8823: add-with-overflow-128.ll
In the bottom-up selection DAG scheduling, handle two-address
instructions that read/write unspillable registers. Treat
the entire chain of two-address nodes as a single live range.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
    llvm/trunk/test/CodeGen/Generic/add-with-overflow-128.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122472&r1=122471&r2=122472&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Dec 22 21:15:51 2010
@@ -247,6 +247,23 @@
   }
 }
 
+/// Call ReleasePred for each predecessor, then update register live def/gen.
+/// Always update LiveRegDefs for a register dependence even if the current SU
+/// also defines the register. This effectively create one large live range
+/// across a sequence of two-address node. This is important because the
+/// entire chain must be scheduled together. Example:
+///
+/// flags = (3) add
+/// flags = (2) addc flags
+/// flags = (1) addc flags
+///
+/// results in
+///
+/// LiveRegDefs[flags] = 3
+/// LiveRegCycles[flags] = 1
+///
+/// If (2) addc is unscheduled, then (1) addc must also be unscheduled to avoid
+/// interference on flags.
 void ScheduleDAGRRList::ReleasePredecessors(SUnit *SU, unsigned CurCycle) {
   // Bottom up: release predecessors
   for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
@@ -257,9 +274,12 @@
       // expensive to copy the register. Make sure nothing that can
       // clobber the register is scheduled between the predecessor and
       // this node.
-      if (!LiveRegDefs[I->getReg()]) {
+      SUnit *&RegDef = LiveRegDefs[I->getReg()];
+      assert((!RegDef || RegDef == SU || RegDef == I->getSUnit()) &&
+             "interference on register dependence");
+      RegDef = I->getSUnit();
+      if (!LiveRegCycles[I->getReg()]) {
         ++NumLiveRegs;
-        LiveRegDefs[I->getReg()] = I->getSUnit();
         LiveRegCycles[I->getReg()] = CurCycle;
       }
     }
@@ -284,20 +304,19 @@
 
   AvailableQueue->ScheduledNode(SU);
 
+  // Update liveness of predecessors before successors to avoid treating a
+  // two-address node as a live range def.
   ReleasePredecessors(SU, CurCycle);
 
   // Release all the implicit physical register defs that are live.
   for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
        I != E; ++I) {
-    if (I->isAssignedRegDep()) {
-      if (LiveRegCycles[I->getReg()] == I->getSUnit()->getHeight()) {
-        assert(NumLiveRegs > 0 && "NumLiveRegs is already zero!");
-        assert(LiveRegDefs[I->getReg()] == SU &&
-               "Physical register dependency violated?");
-        --NumLiveRegs;
-        LiveRegDefs[I->getReg()] = NULL;
-        LiveRegCycles[I->getReg()] = 0;
-      }
+    // LiveRegDegs[I->getReg()] != SU when SU is a two-address node.
+    if (I->isAssignedRegDep() && LiveRegDefs[I->getReg()] == SU) {
+      assert(NumLiveRegs > 0 && "NumLiveRegs is already zero!");
+      --NumLiveRegs;
+      LiveRegDefs[I->getReg()] = NULL;
+      LiveRegCycles[I->getReg()] = 0;
     }
   }
 
@@ -341,8 +360,10 @@
   for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
        I != E; ++I) {
     if (I->isAssignedRegDep()) {
+      // This becomes the nearest def. Note that an earlier def may still be
+      // pending if this is a two-address node.
+      LiveRegDefs[I->getReg()] = SU;
       if (!LiveRegDefs[I->getReg()]) {
-        LiveRegDefs[I->getReg()] = SU;
         ++NumLiveRegs;
       }
       if (I->getSUnit()->getHeight() < LiveRegCycles[I->getReg()])

Modified: llvm/trunk/test/CodeGen/Generic/add-with-overflow-128.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/add-with-overflow-128.ll?rev=122472&r1=122471&r2=122472&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Generic/add-with-overflow-128.ll (original)
+++ llvm/trunk/test/CodeGen/Generic/add-with-overflow-128.ll Wed Dec 22 21:15:51 2010
@@ -1,6 +1,4 @@
-; RUN: true
-; FIXME: TEmporarily disabled: PR8823
-; llc < %s
+; RUN: llc < %s
 
 @ok = internal constant [4 x i8] c"%d\0A\00"
 @no = internal constant [4 x i8] c"no\0A\00"





More information about the llvm-commits mailing list