From 55768d763d3d955c07d5819c3ef2e9d1ca6d2baf Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Sat, 12 Mar 2011 01:50:35 +0000 Subject: [PATCH] That's it, I am declaring this a failure of the C++03 STL. There are too many compatibility problems with using mixed types in std::upper_bound, and I don't want to spend 110 lines of boilerplate setting up a call to a 10-line function. Binary search is not /that/ hard to implement correctly. I tried terminating the binary search with a linear search, but that actually made the algorithm slower against my expectation. Most live intervals have less than 4 segments. The early test against endIndex() does pay, and this version is 25% faster than plain std::upper_bound(). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127522 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveInterval.cpp | 134 ++++------------------------------- 1 file changed, 15 insertions(+), 119 deletions(-) diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 1b446e69d3d..18ec9d56672 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -30,126 +30,22 @@ #include using namespace llvm; -// SlotIndexIterator - adapt an iterator over LiveRanges to look -// like an iterator over SlotIndexes by accessing the .end member. -namespace { -struct SlotIndexIterator - : std::iterator { - - SlotIndexIterator() { - } - - explicit SlotIndexIterator(LiveInterval::iterator it) - : it(it) { - } - - SlotIndexIterator(const SlotIndexIterator & that) - : it(that.it) { - } - - SlotIndexIterator & operator=(const SlotIndexIterator & that) { - it = that.it; - return *this; - } - - SlotIndexIterator & operator++() { - ++it; - return *this; - } - - SlotIndexIterator operator++(int) { - SlotIndexIterator that(*this); - ++*this; - return that; - } - - SlotIndexIterator & operator--() { - --it; - return *this; - } - - SlotIndexIterator operator--(int) { - SlotIndexIterator that(*this); - --*this; - return that; - } - - SlotIndexIterator & operator+=(std::ptrdiff_t n) { - it += n; - return *this; - } - - SlotIndexIterator & operator-=(std::ptrdiff_t n) { - it -= n; - return *this; - } - - friend bool operator==(SlotIndexIterator lhs, SlotIndexIterator rhs) { - return lhs.it == rhs.it; - } - - friend bool operator!=(SlotIndexIterator lhs, SlotIndexIterator rhs) { - return lhs.it != rhs.it; - } - - friend bool operator<(SlotIndexIterator lhs, SlotIndexIterator rhs) { - return lhs.it < rhs.it; - } - - friend bool operator<=(SlotIndexIterator lhs, SlotIndexIterator rhs) { - return lhs.it <= rhs.it; - } - - friend bool operator>(SlotIndexIterator lhs, SlotIndexIterator rhs) { - return lhs.it > rhs.it; - } - - friend bool operator>=(SlotIndexIterator lhs, SlotIndexIterator rhs) { - return lhs.it >= rhs.it; - } - - friend SlotIndexIterator operator+(SlotIndexIterator that, std::ptrdiff_t n) { - return SlotIndexIterator(that.it + n); - } - - friend SlotIndexIterator operator+(std::ptrdiff_t n, SlotIndexIterator that) { - return SlotIndexIterator(n + that.it); - } - - friend SlotIndexIterator operator-(SlotIndexIterator that, std::ptrdiff_t n) { - return SlotIndexIterator(that.it - n); - } - - friend std::ptrdiff_t operator-(SlotIndexIterator lhs, SlotIndexIterator rhs) { - return lhs.it - rhs.it; - } - - reference operator*() const { - return it->end; - } - - reference operator[](std::ptrdiff_t n) const { - return it[n].end; - } - - pointer operator->() const { - return &it->end; - } - - LiveInterval::iterator base() const { - return it; - } - -private: - LiveInterval::iterator it; -}; -} - LiveInterval::iterator LiveInterval::find(SlotIndex Pos) { - assert(Pos.isValid() && "Cannot search for an invalid index"); - return std::upper_bound( - SlotIndexIterator(begin()), - SlotIndexIterator(end()), Pos).base(); + // This algorithm is basically std::upper_bound. + // Unfortunately, std::upper_bound cannot be used with mixed types until we + // adopt C++0x. Many libraries can do it, but not all. + if (empty() || Pos >= endIndex()) + return end(); + iterator I = begin(); + size_t Len = ranges.size(); + do { + size_t Mid = Len >> 1; + if (Pos < I[Mid].end) + Len = Mid; + else + I += Mid + 1, Len -= Mid + 1; + } while (Len); + return I; } /// killedInRange - Return true if the interval has kills in [Start,End). -- 2.34.1