From 181e0bdafaf33524a9a7f082caf5459615f4ab30 Mon Sep 17 00:00:00 2001 From: Stepan Dyatkovskiy Date: Tue, 3 Jul 2012 13:29:14 +0000 Subject: Part of r159527. Splitted into series of patches and gone with fixed PR13256: 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 | 86 +++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) (limited to 'include/llvm/Support/IntegersSubsetMapping.h') diff --git a/include/llvm/Support/IntegersSubsetMapping.h b/include/llvm/Support/IntegersSubsetMapping.h index 87d0755c51..458adbe222 100644 --- a/include/llvm/Support/IntegersSubsetMapping.h +++ b/include/llvm/Support/IntegersSubsetMapping.h @@ -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()) -- cgit v1.2.3