Eliminate the last use of InterferenceResult.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 11 Aug 2011 22:46:04 +0000 (22:46 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 11 Aug 2011 22:46:04 +0000 (22:46 +0000)
The Query class now holds two iterators instead of an InterferenceResult
instance. The iterators are used as bookmarks for repeated
collectInterferingVRegs calls.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137380 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/LiveIntervalUnion.cpp
lib/CodeGen/LiveIntervalUnion.h

index cf5fb6a09f14b3424d5e12cf577077c808aa1852..6c3dc16f31eaf6d6fac4d1577f7aac5ffdb6c2c5 100644 (file)
@@ -117,68 +117,35 @@ void LiveIntervalUnion::verify(LiveVirtRegBitSet& VisitedVRegs) {
 //
 // Assumes that segments are sorted by start position in both
 // LiveInterval and LiveSegments.
-void LiveIntervalUnion::Query::findIntersection(InterferenceResult &IR) const {
+void LiveIntervalUnion::Query::findIntersection() {
   // Search until reaching the end of the LiveUnion segments.
   LiveInterval::iterator VirtRegEnd = VirtReg->end();
-  if (IR.VirtRegI == VirtRegEnd)
+  if (VirtRegI == VirtRegEnd)
     return;
-  while (IR.LiveUnionI.valid()) {
+  while (LiveUnionI.valid()) {
     // Slowly advance the live virtual reg iterator until we surpass the next
     // segment in LiveUnion.
     //
     // Note: If this is ever used for coalescing of fixed registers and we have
     // a live vreg with thousands of segments, then change this code to use
     // upperBound instead.
-    IR.VirtRegI = VirtReg->advanceTo(IR.VirtRegI, IR.LiveUnionI.start());
-    if (IR.VirtRegI == VirtRegEnd)
+    VirtRegI = VirtReg->advanceTo(VirtRegI, LiveUnionI.start());
+    if (VirtRegI == VirtRegEnd)
       break; // Retain current (nonoverlapping) LiveUnionI
 
     // VirtRegI may have advanced far beyond LiveUnionI, catch up.
-    IR.LiveUnionI.advanceTo(IR.VirtRegI->start);
+    LiveUnionI.advanceTo(VirtRegI->start);
 
     // Check if no LiveUnionI exists with VirtRegI->Start < LiveUnionI.end
-    if (!IR.LiveUnionI.valid())
+    if (!LiveUnionI.valid())
       break;
-    if (IR.LiveUnionI.start() < IR.VirtRegI->end) {
-      assert(overlap(*IR.VirtRegI, IR.LiveUnionI) &&
-             "upperBound postcondition");
+    if (LiveUnionI.start() < VirtRegI->end) {
+      assert(overlap(*VirtRegI, LiveUnionI) && "upperBound postcondition");
       break;
     }
   }
-  if (!IR.LiveUnionI.valid())
-    IR.VirtRegI = VirtRegEnd;
-}
-
-// Find the first intersection, and cache interference info
-// (retain segment iterators into both VirtReg and LiveUnion).
-const LiveIntervalUnion::InterferenceResult &
-LiveIntervalUnion::Query::firstInterference() {
-  if (CheckedFirstInterference)
-    return FirstInterference;
-  CheckedFirstInterference = true;
-  InterferenceResult &IR = FirstInterference;
-  IR.LiveUnionI.setMap(LiveUnion->getMap());
-
-  // Quickly skip interference check for empty sets.
-  if (VirtReg->empty() || LiveUnion->empty()) {
-    IR.VirtRegI = VirtReg->end();
-  } else if (VirtReg->beginIndex() < LiveUnion->startIndex()) {
-    // VirtReg starts first, perform double binary search.
-    IR.VirtRegI = VirtReg->find(LiveUnion->startIndex());
-    if (IR.VirtRegI != VirtReg->end())
-      IR.LiveUnionI.find(IR.VirtRegI->start);
-  } else {
-    // LiveUnion starts first, perform double binary search.
-    IR.LiveUnionI.find(VirtReg->beginIndex());
-    if (IR.LiveUnionI.valid())
-      IR.VirtRegI = VirtReg->find(IR.LiveUnionI.start());
-    else
-      IR.VirtRegI = VirtReg->end();
-  }
-  findIntersection(FirstInterference);
-  assert((IR.VirtRegI == VirtReg->end() || IR.LiveUnionI.valid())
-         && "Uninitialized iterator");
-  return FirstInterference;
+  if (!LiveUnionI.valid())
+    VirtRegI = VirtRegEnd;
 }
 
 // Scan the vector of interfering virtual registers in this union. Assume it's
@@ -200,37 +167,64 @@ bool LiveIntervalUnion::Query::isSeenInterference(LiveInterval *VirtReg) const {
 // For comments on how to speed it up, see Query::findIntersection().
 unsigned LiveIntervalUnion::Query::
 collectInterferingVRegs(unsigned MaxInterferingRegs) {
-  if (InterferingVRegs.size() >= MaxInterferingRegs)
+  // Fast path return if we already have the desired information.
+  if (SeenAllInterferences || InterferingVRegs.size() >= MaxInterferingRegs)
     return InterferingVRegs.size();
-  InterferenceResult IR = firstInterference();
+
+  // Set up iterators on the first call.
+  if (!CheckedFirstInterference) {
+    CheckedFirstInterference = true;
+    LiveUnionI.setMap(LiveUnion->getMap());
+
+    // Quickly skip interference check for empty sets.
+    if (VirtReg->empty() || LiveUnion->empty()) {
+      VirtRegI = VirtReg->end();
+    } else if (VirtReg->beginIndex() < LiveUnion->startIndex()) {
+      // VirtReg starts first, perform double binary search.
+      VirtRegI = VirtReg->find(LiveUnion->startIndex());
+      if (VirtRegI != VirtReg->end())
+        LiveUnionI.find(VirtRegI->start);
+    } else {
+      // LiveUnion starts first, perform double binary search.
+      LiveUnionI.find(VirtReg->beginIndex());
+      if (LiveUnionI.valid())
+        VirtRegI = VirtReg->find(LiveUnionI.start());
+      else
+        VirtRegI = VirtReg->end();
+    }
+    findIntersection();
+    assert((VirtRegI == VirtReg->end() || LiveUnionI.valid())
+           && "Uninitialized iterator");
+  }
+
   LiveInterval::iterator VirtRegEnd = VirtReg->end();
   LiveInterval *RecentInterferingVReg = NULL;
-  if (IR.VirtRegI != VirtRegEnd) while (IR.LiveUnionI.valid()) {
+  if (VirtRegI != VirtRegEnd) while (LiveUnionI.valid()) {
     // Advance the union's iterator to reach an unseen interfering vreg.
     do {
-      if (IR.LiveUnionI.value() == RecentInterferingVReg)
+      if (LiveUnionI.value() == RecentInterferingVReg)
         continue;
 
-      if (!isSeenInterference(IR.LiveUnionI.value()))
+      if (!isSeenInterference(LiveUnionI.value()))
         break;
 
       // Cache the most recent interfering vreg to bypass isSeenInterference.
-      RecentInterferingVReg = IR.LiveUnionI.value();
+      RecentInterferingVReg = LiveUnionI.value();
 
-    } while ((++IR.LiveUnionI).valid());
-    if (!IR.LiveUnionI.valid())
+    } while ((++LiveUnionI).valid());
+    if (!LiveUnionI.valid())
       break;
 
     // Advance the VirtReg iterator until surpassing the next segment in
     // LiveUnion.
-    IR.VirtRegI = VirtReg->advanceTo(IR.VirtRegI, IR.LiveUnionI.start());
-    if (IR.VirtRegI == VirtRegEnd)
+    VirtRegI = VirtReg->advanceTo(VirtRegI, LiveUnionI.start());
+    if (VirtRegI == VirtRegEnd)
       break;
 
     // Check for intersection with the union's segment.
-    if (overlap(*IR.VirtRegI, IR.LiveUnionI)) {
+    if (overlap(*VirtRegI, LiveUnionI)) {
 
-      if (!IR.LiveUnionI.value()->isSpillable())
+      if (!LiveUnionI.value()->isSpillable())
         SeenUnspillableVReg = true;
 
       if (InterferingVRegs.size() == MaxInterferingRegs)
@@ -238,17 +232,17 @@ collectInterferingVRegs(unsigned MaxInterferingRegs) {
         // interference exists beyond those we collected.
         return MaxInterferingRegs;
 
-      InterferingVRegs.push_back(IR.LiveUnionI.value());
+      InterferingVRegs.push_back(LiveUnionI.value());
 
       // Cache the most recent interfering vreg to bypass isSeenInterference.
-      RecentInterferingVReg = IR.LiveUnionI.value();
-      ++IR.LiveUnionI;
+      RecentInterferingVReg = LiveUnionI.value();
+      ++LiveUnionI;
 
       continue;
     }
     // VirtRegI may have advanced far beyond LiveUnionI,
     // do a fast intersection test to "catch up"
-    IR.LiveUnionI.advanceTo(IR.VirtRegI->start);
+    LiveUnionI.advanceTo(VirtRegI->start);
   }
   SeenAllInterferences = true;
   return InterferingVRegs.size();
index 570ad94b77eaa803064c6584e3bb71b8a3bfcc92..8f4bb00c94b06c2ac9e02deae46777f2e093d046 100644 (file)
@@ -142,7 +142,8 @@ public:
   class Query {
     LiveIntervalUnion *LiveUnion;
     LiveInterval *VirtReg;
-    InterferenceResult FirstInterference;
+    LiveInterval::iterator VirtRegI; // current position in VirtReg
+    SegmentIter LiveUnionI;          // current position in LiveUnion
     SmallVector<LiveInterval*,4> InterferingVRegs;
     bool CheckedFirstInterference;
     bool SeenAllInterferences;
@@ -217,8 +218,7 @@ public:
     void operator=(const Query&); // DO NOT IMPLEMENT
 
     // Private interface for queries
-    const InterferenceResult &firstInterference();
-    void findIntersection(InterferenceResult &IR) const;
+    void findIntersection();
   };
 };