Part of r159527. Splitted into series of patches and gone with fixed PR13256:
authorStepan Dyatkovskiy <stpworld@narod.ru>
Tue, 3 Jul 2012 13:29:14 +0000 (13:29 +0000)
committerStepan Dyatkovskiy <stpworld@narod.ru>
Tue, 3 Jul 2012 13:29:14 +0000 (13:29 +0000)
Optimized diff operation: implemented the case when LHS and RHS subsets contains single numbers only.

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

include/llvm/Support/IntegersSubsetMapping.h

index 87d0755c5170fda30ea7820905d4f7f0f176a25f..458adbe22231380232154c31368a003ee929f25d 100644 (file)
@@ -74,6 +74,7 @@ protected:
   
   CaseItems Items;
   bool Sorted;
+  bool SingleNumbersOnly;
   
   bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
     return LItem->first.getHigh() >= RItem->first.getLow();
@@ -245,6 +246,48 @@ protected:
     bool isLOpened() { return State == L_OPENED; }
     bool isROpened() { return State == R_OPENED; }
   };
+  
+  void diff_single_numbers(self *LExclude, self *Intersection, self *RExclude,
+                               const self& RHS) {
+    
+    CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
+    CaseItemConstIt el = Items.end(), er = RHS.Items.end();
+    while (L != el && R != er) {
+      const Cluster &LCluster = *L;
+      const RangeEx &LRange = LCluster.first;
+      const Cluster &RCluster = *R;
+      const RangeEx &RRange = RCluster.first;
+      
+      if (LRange.getLow() < RRange.getLow()) {
+        if (LExclude)
+          LExclude->add(LRange.getLow(), LCluster.second);
+        ++L;
+      } else if (LRange.getLow() > RRange.getLow()) {
+        if (RExclude)
+          RExclude->add(RRange.getLow(), RCluster.second);
+        ++R;
+      } else {
+        if (Intersection)
+          Intersection->add(LRange.getLow(), LCluster.second);
+        ++L;
+        ++R;
+      }
+    }
+    
+    if (L != Items.end()) {
+      if (LExclude)
+        do {
+            LExclude->add(L->first, L->second);
+            ++L;
+        } while (L != Items.end());
+    } else if (R != RHS.Items.end()) {
+      if (RExclude)
+        do {
+          RExclude->add(R->first, R->second);
+          ++R;
+        } while (R != RHS.Items.end());
+    }
+  }  
 
 public:
   
@@ -259,6 +302,7 @@ public:
   
   IntegersSubsetMapping() {
     Sorted = false;
+    SingleNumbersOnly = true;
   }
   
   bool verify(RangeIterator& errItem) {
@@ -324,7 +368,8 @@ public:
   }   
   void add(const RangeEx &R, SuccessorClass *S = 0) {
     Items.push_back(std::make_pair(R, S));
-    Sorted = false;
+    if (!R.isSingleNumber())
+      SingleNumbersOnly = false;
   }  
   
   /// Adds all ranges and values from given ranges set to the current
@@ -338,6 +383,8 @@ public:
   
   void add(self& RHS) {
     Items.insert(Items.end(), RHS.Items.begin(), RHS.Items.end());
+    if (!RHS.SingleNumbersOnly)
+      SingleNumbersOnly = false;
   }
   
   void add(const RangesCollection& RHS, SuccessorClass *S = 0) {
@@ -355,10 +402,16 @@ public:
   void diff(self *LExclude, self *Intersection, self *RExclude,
                              const self& RHS) {
     
+    if (SingleNumbersOnly && RHS.SingleNumbersOnly) {
+      diff_single_numbers(LExclude, Intersection, RExclude, RHS);
+      return;
+    }
+    
     DiffStateMachine Machine(LExclude, Intersection, RExclude);
     
     CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
-    while (L != Items.end() && R != RHS.Items.end()) {
+    CaseItemConstIt el = Items.end(), er = RHS.Items.end();
+    while (L != el && R != er) {
       const Cluster &LCluster = *L;
       const RangeEx &LRange = LCluster.first;
       const Cluster &RCluster = *R;
@@ -377,7 +430,36 @@ public:
         ++R;
         continue;
       }
+
+      if (LRange.isSingleNumber() && RRange.isSingleNumber()) {
+        Machine.onRLOpen(LRange.getLow(), LCluster.second, RCluster.second);
+        Machine.onRLClose(LRange.getLow());
+        ++L;
+        ++R;
+        continue;
+      }
       
+      if (LRange.isSingleNumber()) {
+        Machine.onLOpen(LRange.getLow(), LCluster.second);
+        Machine.onLClose(LRange.getLow());
+        ++L;
+        while(L != Items.end() && L->first.getHigh() < RRange.getHigh()) {
+          Machine.onLOpen(LRange.getLow(), LCluster.second);
+          Machine.onLClose(LRange.getLow());
+          ++L;
+        }
+        continue;
+      } else if (RRange.isSingleNumber()) {
+        Machine.onROpen(R->first.getLow(), R->second);
+        Machine.onRClose(R->first.getHigh());
+        ++R;
+        while(R != RHS.Items.end() && R->first.getHigh() < LRange.getHigh()) {
+          Machine.onROpen(R->first.getLow(), R->second);
+          Machine.onRClose(R->first.getHigh());
+          ++R;
+        }
+        continue;
+      } else
       if (LRange.getLow() < RRange.getLow()) {
         // May be opened in previous iteration.
         if (!Machine.isLOpened())