[llvm] r285957 - [ADT] IntervalMap: fix setStart and setStop

Michael LeMay via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 3 12:14:47 PDT 2016


Author: mdlemay
Date: Thu Nov  3 14:14:46 2016
New Revision: 285957

URL: http://llvm.org/viewvc/llvm-project?rev=285957&view=rev
Log:
[ADT] IntervalMap: fix setStart and setStop

Summary:
These functions currently require that the new closed interval has a length of
at least 2.  They also currently permit empty half-open intervals.  This patch
defines nonEmpty in each traits structure and uses it to correct the
implementations of setStart and setStop.

Reviewers: stoklund, chandlerc

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D26064

Modified:
    llvm/trunk/include/llvm/ADT/IntervalMap.h
    llvm/trunk/unittests/ADT/IntervalMapTest.cpp

Modified: llvm/trunk/include/llvm/ADT/IntervalMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/IntervalMap.h?rev=285957&r1=285956&r2=285957&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/IntervalMap.h (original)
+++ llvm/trunk/include/llvm/ADT/IntervalMap.h Thu Nov  3 14:14:46 2016
@@ -150,6 +150,12 @@ struct IntervalMapInfo {
     return a+1 == b;
   }
 
+  /// nonEmpty - Return true if [a;b] is non-empty.
+  /// This is a <= b for a closed interval, a < b for [a;b) half-open intervals.
+  static inline bool nonEmpty(const T &a, const T &b) {
+    return a <= b;
+  }
+
 };
 
 template <typename T>
@@ -170,6 +176,11 @@ struct IntervalMapHalfOpenInfo {
     return a == b;
   }
 
+  /// nonEmpty - Return true if [a;b) is non-empty.
+  static inline bool nonEmpty(const T &a, const T &b) {
+    return a < b;
+  }
+
 };
 
 /// IntervalMapImpl - Namespace used for IntervalMap implementation details.
@@ -1669,7 +1680,7 @@ iterator::setNodeStop(unsigned Level, Ke
 template <typename KeyT, typename ValT, unsigned N, typename Traits>
 void IntervalMap<KeyT, ValT, N, Traits>::
 iterator::setStart(KeyT a) {
-  assert(Traits::stopLess(a, this->stop()) && "Cannot move start beyond stop");
+  assert(Traits::nonEmpty(a, this->stop()) && "Cannot move start beyond stop");
   KeyT &CurStart = this->unsafeStart();
   if (!Traits::startLess(a, CurStart) || !canCoalesceLeft(a, this->value())) {
     CurStart = a;
@@ -1685,7 +1696,7 @@ iterator::setStart(KeyT a) {
 template <typename KeyT, typename ValT, unsigned N, typename Traits>
 void IntervalMap<KeyT, ValT, N, Traits>::
 iterator::setStop(KeyT b) {
-  assert(Traits::stopLess(this->start(), b) && "Cannot move stop beyond start");
+  assert(Traits::nonEmpty(this->start(), b) && "Cannot move stop beyond start");
   if (Traits::startLess(b, this->stop()) ||
       !canCoalesceRight(b, this->value())) {
     setStopUnchecked(b);

Modified: llvm/trunk/unittests/ADT/IntervalMapTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/IntervalMapTest.cpp?rev=285957&r1=285956&r2=285957&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/IntervalMapTest.cpp (original)
+++ llvm/trunk/unittests/ADT/IntervalMapTest.cpp Thu Nov  3 14:14:46 2016
@@ -15,6 +15,8 @@ using namespace llvm;
 namespace {
 
 typedef IntervalMap<unsigned, unsigned, 4> UUMap;
+typedef IntervalMap<unsigned, unsigned, 4,
+                    IntervalMapHalfOpenInfo<unsigned>> UUHalfOpenMap;
 
 // Empty map tests
 TEST(IntervalMapTest, EmptyMap) {
@@ -125,18 +127,63 @@ TEST(IntervalMapTest, SingleEntryMap) {
   EXPECT_EQ(200u, I.stop());
   EXPECT_EQ(2u, I.value());
 
+  // Shrink the interval to have a length of 1
+  I.setStop(150);
+  ASSERT_TRUE(I.valid());
+  EXPECT_EQ(150u, I.start());
+  EXPECT_EQ(150u, I.stop());
+  EXPECT_EQ(2u, I.value());
+
   I.setStop(160);
   ASSERT_TRUE(I.valid());
   EXPECT_EQ(150u, I.start());
   EXPECT_EQ(160u, I.stop());
   EXPECT_EQ(2u, I.value());
 
+  // Shrink the interval to have a length of 1
+  I.setStart(160);
+  ASSERT_TRUE(I.valid());
+  EXPECT_EQ(160u, I.start());
+  EXPECT_EQ(160u, I.stop());
+  EXPECT_EQ(2u, I.value());
+
   // Erase last elem.
   I.erase();
   EXPECT_TRUE(map.empty());
   EXPECT_EQ(0, std::distance(map.begin(), map.end()));
 }
 
+// Single entry half-open map tests
+TEST(IntervalMapTest, SingleEntryHalfOpenMap) {
+  UUHalfOpenMap::Allocator allocator;
+  UUHalfOpenMap map(allocator);
+  map.insert(100, 150, 1);
+  EXPECT_FALSE(map.empty());
+
+  UUHalfOpenMap::iterator I = map.begin();
+  ASSERT_TRUE(I.valid());
+
+  // Shrink the interval to have a length of 1
+  I.setStart(149);
+  ASSERT_TRUE(I.valid());
+  EXPECT_EQ(149u, I.start());
+  EXPECT_EQ(150u, I.stop());
+  EXPECT_EQ(1u, I.value());
+
+  I.setStop(160);
+  ASSERT_TRUE(I.valid());
+  EXPECT_EQ(149u, I.start());
+  EXPECT_EQ(160u, I.stop());
+  EXPECT_EQ(1u, I.value());
+
+  // Shrink the interval to have a length of 1
+  I.setStop(150);
+  ASSERT_TRUE(I.valid());
+  EXPECT_EQ(149u, I.start());
+  EXPECT_EQ(150u, I.stop());
+  EXPECT_EQ(1u, I.value());
+}
+
 // Flat coalescing tests.
 TEST(IntervalMapTest, RootCoalescing) {
   UUMap::Allocator allocator;




More information about the llvm-commits mailing list