[llvm-commits] [llvm] r144149 - /llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp

Jakob Stoklund Olesen stoklund at 2pi.dk
Tue Nov 8 16:06:18 PST 2011


Author: stoklund
Date: Tue Nov  8 18:06:18 2011
New Revision: 144149

URL: http://llvm.org/viewvc/llvm-project?rev=144149&view=rev
Log:
Link to the live DomainValue after merging.

When merging two uncollapsed DomainValues, place a link to the active
DomainValue from the passive DomainValue.  This allows old stale
references to the passive DomainValue to be updated to point to the
active DomainValue.

The new resolve() function finds the active DomainValue and updates the
pointer.

This change makes old live-out lists more useful since they may contain
uncollapsed DomainValues that have since been merged into other
DomainValues.

Modified:
    llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp

Modified: llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp?rev=144149&r1=144148&r2=144149&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp (original)
+++ llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp Tue Nov  8 18:06:18 2011
@@ -60,6 +60,11 @@
   // Position of the last defining instruction.
   unsigned Dist;
 
+  // Pointer to the next DomainValue in a chain.  When two DomainValues are
+  // merged, Victim.Next is set to point to Victor, so old DomainValue
+  // references can be updated by folowing the chain.
+  DomainValue *Next;
+
   // Twiddleable instructions using or defining these registers.
   SmallVector<MachineInstr*, 8> Instrs;
 
@@ -94,8 +99,10 @@
 
   DomainValue() : Refs(0) { clear(); }
 
+  // Clear this DomainValue and point to next which has all its data.
   void clear() {
     AvailableDomains = Dist = 0;
+    Next = 0;
     Instrs.clear();
   }
 };
@@ -139,7 +146,12 @@
 
   // DomainValue allocation.
   DomainValue *alloc(int domain = -1);
+  DomainValue *retain(DomainValue *DV) {
+    if (DV) ++DV->Refs;
+    return DV;
+  }
   void release(DomainValue*);
+  DomainValue *resolve(DomainValue*&);
 
   // LiveRegs manipulations.
   void setLiveReg(int rx, DomainValue *DV);
@@ -174,22 +186,46 @@
   if (domain >= 0)
     dv->addDomain(domain);
   assert(dv->Refs == 0 && "Reference count wasn't cleared");
+  assert(!dv->Next && "Chained DomainValue shouldn't have been recycled");
   return dv;
 }
 
 /// release - Release a reference to DV.  When the last reference is released,
 /// collapse if needed.
 void ExeDepsFix::release(DomainValue *DV) {
-  assert(DV && DV->Refs && "Bad DomainValue");
-  if (--DV->Refs)
-    return;
-
-  // There are no more DV references. Collapse any contained instructions.
-  if (DV->AvailableDomains && !DV->isCollapsed())
-    collapse(DV, DV->getFirstDomain());
+  while (DV) {
+    assert(DV->Refs && "Bad DomainValue");
+    if (--DV->Refs)
+      return;
+
+    // There are no more DV references. Collapse any contained instructions.
+    if (DV->AvailableDomains && !DV->isCollapsed())
+      collapse(DV, DV->getFirstDomain());
+
+    DomainValue *Next = DV->Next;
+    DV->clear();
+    Avail.push_back(DV);
+    // Also release the next DomainValue in the chain.
+    DV = Next;
+  }
+}
 
-  DV->clear();
-  Avail.push_back(DV);
+/// resolve - Follow the chain of dead DomainValues until a live DomainValue is
+/// reached.  Update the referenced pointer when necessary.
+DomainValue *ExeDepsFix::resolve(DomainValue *&DVRef) {
+  DomainValue *DV = DVRef;
+  if (!DV || !DV->Next)
+    return DV;
+
+  // DV has a chain. Find the end.
+  do DV = DV->Next;
+  while (DV->Next);
+
+  // Update DVRef to point to DV.
+  retain(DV);
+  release(DVRef);
+  DVRef = DV;
+  return DV;
 }
 
 /// Set LiveRegs[rx] = dv, updating reference counts.
@@ -204,8 +240,7 @@
     return;
   if (LiveRegs[rx])
     release(LiveRegs[rx]);
-  LiveRegs[rx] = dv;
-  if (dv) ++dv->Refs;
+  LiveRegs[rx] = retain(dv);
 }
 
 // Kill register rx, recycle or collapse any DomainValue.
@@ -273,6 +308,8 @@
 
   // Clear the old DomainValue so we won't try to swizzle instructions twice.
   B->clear();
+  // All uses of B are referred to A.
+  B->Next = retain(A);
 
   for (unsigned rx = 0; rx != NumRegs; ++rx)
     if (LiveRegs[rx] == B)
@@ -290,8 +327,8 @@
            pe = MBB->pred_end(); pi != pe; ++pi) {
       LiveOutMap::const_iterator fi = LiveOuts.find(*pi);
       if (fi == LiveOuts.end()) continue;
-      DomainValue *pdv = fi->second[rx];
-      if (!pdv || !pdv->AvailableDomains) continue;
+      DomainValue *pdv = resolve(fi->second[rx]);
+      if (!pdv) continue;
       if (!LiveRegs || !LiveRegs[rx]) {
         setLiveReg(rx, pdv);
         continue;





More information about the llvm-commits mailing list