Bug 1012964 - IonMonkey: Optimize LiveInterval::addRange. r=bhackett
authorDan Gohman <sunfish@mozilla.com>
Tue, 20 May 2014 13:36:40 -0700
changeset 184077 24ddf040a705131f673b7b6ce7defb811c9b8973
parent 184076 f5ea20c06879ea9564e5a289dd842bbd506ac7a5
child 184078 a6cf64544f9b9c82e3bde274db80bd2a2fa3be4e
push id6897
push userryanvm@gmail.com
push dateWed, 21 May 2014 12:56:42 +0000
treeherderfx-team@a971ac323875 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs1012964
milestone32.0a1
Bug 1012964 - IonMonkey: Optimize LiveInterval::addRange. r=bhackett
js/src/jit/LiveRangeAllocator.cpp
mfbt/Vector.h
--- a/js/src/jit/LiveRangeAllocator.cpp
+++ b/js/src/jit/LiveRangeAllocator.cpp
@@ -71,16 +71,17 @@ LiveInterval::Range::intersect(const Ran
     if (innerFrom != innerTo)
         *inside = Range(innerFrom, innerTo);
 }
 
 bool
 LiveInterval::addRangeAtHead(CodePosition from, CodePosition to)
 {
     JS_ASSERT(from < to);
+    JS_ASSERT(ranges_.empty() || from <= ranges_.back().from);
 
     Range newRange(from, to);
 
     if (ranges_.empty())
         return ranges_.append(newRange);
 
     Range &first = ranges_.back();
     if (to < first.from)
@@ -105,44 +106,49 @@ bool
 LiveInterval::addRange(CodePosition from, CodePosition to)
 {
     JS_ASSERT(from < to);
 
     Range newRange(from, to);
 
     Range *i;
     // Find the location to insert the new range
-    for (i = ranges_.end() - 1; i >= ranges_.begin(); i--) {
-        if (newRange.from <= i->to) {
-            if (i->from < newRange.from)
-                newRange.from = i->from;
+    for (i = ranges_.end(); i > ranges_.begin(); i--) {
+        if (newRange.from <= i[-1].to) {
+            if (i[-1].from < newRange.from)
+                newRange.from = i[-1].from;
             break;
         }
     }
     // Perform coalescing on overlapping ranges
-    for (; i >= ranges_.begin(); i--) {
-        if (newRange.to < i->from)
+    Range *j = i;
+    for (; i > ranges_.begin(); i--) {
+        if (newRange.to < i[-1].from)
             break;
-        if (newRange.to < i->to)
-            newRange.to = i->to;
-        ranges_.erase(i);
+        if (newRange.to < i[-1].to)
+            newRange.to = i[-1].to;
     }
 
-    return ranges_.insert(i + 1, newRange);
+    if (i == j)
+        return ranges_.insert(i, newRange);
+
+    i[0] = newRange;
+    ranges_.erase(i + 1, j);
+    return true;
 }
 
 void
 LiveInterval::setFrom(CodePosition from)
 {
     while (!ranges_.empty()) {
         if (ranges_.back().to < from) {
-            ranges_.erase(&ranges_.back());
+            ranges_.popBack();
         } else {
             if (from == ranges_.back().to)
-                ranges_.erase(&ranges_.back());
+                ranges_.popBack();
             else
                 ranges_.back().from = from;
             break;
         }
     }
 }
 
 bool
--- a/mfbt/Vector.h
+++ b/mfbt/Vector.h
@@ -539,16 +539,22 @@ class VectorBase : private AllocPolicy
 
     /**
      * Removes the element |t|, which must fall in the bounds [begin, end),
      * shifting existing elements from |t + 1| onward one position lower.
      */
     void erase(T* t);
 
     /**
+     * Removes the elements [|b|, |e|), which must fall in the bounds [begin, end),
+     * shifting existing elements from |e + 1| onward to b's old position.
+     */
+    void erase(T* b, T *e);
+
+    /**
      * Measure the size of the vector's heap-allocated storage.
      */
     size_t sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const;
 
     /**
      * Like sizeOfExcludingThis, but also measures the size of the vector
      * object (which must be heap-allocated) itself.
      */
@@ -969,20 +975,32 @@ VectorBase<T, N, AP, TV>::insert(T* p, U
 
 template<typename T, size_t N, class AP, class TV>
 inline void
 VectorBase<T, N, AP, TV>::erase(T* it)
 {
   MOZ_ASSERT(begin() <= it);
   MOZ_ASSERT(it < end());
   while (it + 1 < end()) {
-    *it = *(it + 1);
+    *it = Move(*(it + 1));
     ++it;
   }
-    popBack();
+  popBack();
+}
+
+template<typename T, size_t N, class AP, class TV>
+inline void
+VectorBase<T, N, AP, TV>::erase(T* b, T *e)
+{
+  MOZ_ASSERT(begin() <= b);
+  MOZ_ASSERT(b <= e);
+  MOZ_ASSERT(e <= end());
+  while (e < end())
+    *b++ = Move(*e++);
+  shrinkBy(e - b);
 }
 
 template<typename T, size_t N, class AP, class TV>
 template<typename U>
 MOZ_ALWAYS_INLINE bool
 VectorBase<T, N, AP, TV>::append(const U* insBegin, const U* insEnd)
 {
   MOZ_REENTRANCY_GUARD_ET_AL;