Bug 900683 - IonMonkey: Register allocation niceties. r=bhackett
authorDan Gohman <sunfish@google.com>
Tue, 24 Sep 2013 09:25:13 -0700
changeset 162276 2f924314efe888f29785dd9bbb49e2451662662d
parent 162275 726355fba9b6ad2e2ccebeaef8f1b285fd8206e5
child 162277 e894f34f6286c8d95448de70e74ef2024eecc231
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs900683
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 900683 - IonMonkey: Register allocation niceties. r=bhackett
js/src/jit/BacktrackingAllocator.cpp
js/src/jit/BacktrackingAllocator.h
js/src/jit/InlineList.h
js/src/jit/LiveRangeAllocator.h
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -782,25 +782,25 @@ BacktrackingAllocator::distributeUses(Li
 
     return true;
 }
 
 bool
 BacktrackingAllocator::split(LiveInterval *interval,
                              const LiveIntervalVector &newIntervals)
 {
-    JS_ASSERT(newIntervals.length() >= 2);
-
     if (IonSpewEnabled(IonSpew_RegAlloc)) {
         IonSpew(IonSpew_RegAlloc, "splitting interval v%u %s:",
                 interval->vreg(), IntervalString(interval));
         for (size_t i = 0; i < newIntervals.length(); i++)
             IonSpew(IonSpew_RegAlloc, "    %s", IntervalString(newIntervals[i]));
     }
 
+    JS_ASSERT(newIntervals.length() >= 2);
+
     // Find the earliest interval in the new list.
     LiveInterval *first = newIntervals[0];
     for (size_t i = 1; i < newIntervals.length(); i++) {
         if (newIntervals[i]->start() < first->start())
             first = newIntervals[i];
     }
 
     // Replace the old interval in the virtual register's state with the new intervals.
@@ -1760,21 +1760,18 @@ BacktrackingAllocator::splitAcrossCalls(
         LiveInterval *newInterval = newIntervals[i];
         CodePosition start, end;
         if (i == 0 && spillStart != interval->start()) {
             start = interval->start();
             end = spillStart;
         } else {
             start = inputOf(insData[newInterval->usesBegin()->pos].ins());
         }
-        for (UsePositionIterator iter(newInterval->usesBegin());
-             iter != newInterval->usesEnd();
-             iter++) {
-            end = iter->pos.next();
-        }
+        if (newInterval->usesBegin() != newInterval->usesEnd())
+            end = newInterval->usesBack()->pos.next();
         if (!newInterval->addRange(start, end))
             return false;
     }
 
     if (!newIntervals.append(spillInterval))
         return false;
 
     return split(interval, newIntervals) && requeueIntervals(newIntervals);
--- a/js/src/jit/BacktrackingAllocator.h
+++ b/js/src/jit/BacktrackingAllocator.h
@@ -70,16 +70,17 @@ class BacktrackingVirtualRegister : publ
     void setMustCopyInput() {
         mustCopyInput_ = true;
     }
     bool mustCopyInput() {
         return mustCopyInput_;
     }
 
     void setCanonicalSpill(LAllocation alloc) {
+        JS_ASSERT(!alloc.isUse());
         canonicalSpill_ = alloc;
     }
     const LAllocation *canonicalSpill() const {
         return canonicalSpill_.isUse() ? NULL : &canonicalSpill_;
     }
 
     void setCanonicalSpillExclude(CodePosition pos) {
         canonicalSpillExclude_ = pos;
--- a/js/src/jit/InlineList.h
+++ b/js/src/jit/InlineList.h
@@ -88,16 +88,20 @@ class InlineForwardList : protected Inli
         tail_ = t;
     }
     T *popFront() {
         JS_ASSERT(!empty());
         T* result = static_cast<T *>(this->next);
         removeAfter(this, result);
         return result;
     }
+    T *back() {
+        JS_ASSERT(!empty());
+        return static_cast<T *>(tail_);
+    }
     void insertAfter(Node *at, Node *item) {
         modifyCount_++;
         if (at == tail_)
             tail_ = item;
         item->next = at->next;
         at->next = item;
     }
     void removeAfter(Node *at, Node *item) {
--- a/js/src/jit/LiveRangeAllocator.h
+++ b/js/src/jit/LiveRangeAllocator.h
@@ -341,16 +341,20 @@ class LiveInterval
     UsePositionIterator usesBegin() const {
         return uses_.begin();
     }
 
     UsePositionIterator usesEnd() const {
         return uses_.end();
     }
 
+    UsePosition *usesBack() {
+        return uses_.back();
+    }
+
 #ifdef DEBUG
     void validateRanges();
 #endif
 };
 
 /*
  * Represents all of the register allocation state associated with a virtual
  * register, including all associated intervals and pointers to relevant LIR
@@ -362,16 +366,19 @@ class VirtualRegister
     LBlock *block_;
     LInstruction *ins_;
     LDefinition *def_;
     Vector<LiveInterval *, 1, IonAllocPolicy> intervals_;
 
     // Whether def_ is a temp or an output.
     bool isTemp_ : 1;
 
+    void operator=(const VirtualRegister &) MOZ_DELETE;
+    VirtualRegister(const VirtualRegister &) MOZ_DELETE;
+
   public:
     bool init(uint32_t id, LBlock *block, LInstruction *ins, LDefinition *def, bool isTemp) {
         JS_ASSERT(block && !block_);
         id_ = id;
         block_ = block;
         ins_ = ins;
         def_ = def;
         isTemp_ = isTemp;
@@ -442,16 +449,19 @@ class VirtualRegister
 // VirtualRegister extended with any allocator specific state for the vreg.
 template <typename VREG>
 class VirtualRegisterMap
 {
   private:
     VREG *vregs_;
     uint32_t numVregs_;
 
+    void operator=(const VirtualRegisterMap &) MOZ_DELETE;
+    VirtualRegisterMap(const VirtualRegisterMap &) MOZ_DELETE;
+
   public:
     VirtualRegisterMap()
       : vregs_(NULL),
         numVregs_(0)
     { }
 
     bool init(MIRGenerator *gen, uint32_t numVregs) {
         vregs_ = gen->allocate<VREG>(numVregs);