IntervalMap iterators are heavyweight, so avoid copying them around and use
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 9 Dec 2010 01:06:52 +0000 (01:06 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 9 Dec 2010 01:06:52 +0000 (01:06 +0000)
references instead.

Similarly, IntervalMap::begin() is almost as expensive as find(), so use find(x)
instead of begin().advanceTo(x);

This makes RegAllocBasic run another 5% faster.

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

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

index 4b9a2d302c09cd2e7de8cdef47e13bc8b2a95578..1fca034fdcb33acfae378b3e508fb927c04cc4be 100644 (file)
@@ -144,12 +144,29 @@ void LiveIntervalUnion::Query::findIntersection(InterferenceResult &IR) const {
 
 // Find the first intersection, and cache interference info
 // (retain segment iterators into both VirtReg and LiveUnion).
-LiveIntervalUnion::InterferenceResult
+const LiveIntervalUnion::InterferenceResult &
 LiveIntervalUnion::Query::firstInterference() {
-  if (FirstInterference != LiveIntervalUnion::InterferenceResult()) {
+  if (CheckedFirstInterference)
     return FirstInterference;
+  CheckedFirstInterference = true;
+  InterferenceResult &IR = FirstInterference;
+
+  // 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 = LiveUnion->find(IR.VirtRegI->start);
+  } else {
+    // LiveUnion starts first, perform double binary search.
+    IR.LiveUnionI = LiveUnion->find(VirtReg->beginIndex());
+    if (IR.LiveUnionI.valid())
+      IR.VirtRegI = VirtReg->find(IR.LiveUnionI.start());
+    else
+      IR.VirtRegI = VirtReg->end();
   }
-  FirstInterference = InterferenceResult(VirtReg->begin(), LiveUnion->begin());
   findIntersection(FirstInterference);
   return FirstInterference;
 }
index 0c9a13a606c7f1c7d7304ee47f5a6c9a87369bce..442558218c29ec5880fa8b0062c09ef717804127 100644 (file)
@@ -75,7 +75,9 @@ public:
   // by their starting position.
   SegmentIter begin() { return Segments.begin(); }
   SegmentIter end() { return Segments.end(); }
+  SegmentIter find(SlotIndex x) { return Segments.find(x); }
   bool empty() { return Segments.empty(); }
+  SlotIndex startIndex() { return Segments.start(); }
 
   // Add a live virtual register to this union and merge its segments.
   void unify(LiveInterval &VirtReg);
@@ -135,6 +137,7 @@ public:
     LiveInterval *VirtReg;
     InterferenceResult FirstInterference;
     SmallVector<LiveInterval*,4> InterferingVRegs;
+    bool CheckedFirstInterference;
     bool SeenAllInterferences;
     bool SeenUnspillableVReg;
 
@@ -149,8 +152,8 @@ public:
     void clear() {
       LiveUnion = NULL;
       VirtReg = NULL;
-      FirstInterference = InterferenceResult();
       InterferingVRegs.clear();
+      CheckedFirstInterference = false;
       SeenAllInterferences = false;
       SeenUnspillableVReg = false;
     }
@@ -187,7 +190,7 @@ public:
 
     // Get the first pair of interfering segments, or a noninterfering result.
     // This initializes the firstInterference_ cache.
-    InterferenceResult firstInterference();
+    const InterferenceResult &firstInterference();
 
     // Treat the result as an iterator and advance to the next interfering pair
     // of segments. Visiting each unique interfering pairs means that the same