Bug 943425 - IonMonkey: Avoid creating unused LMoveGroups. r=bhackett
authorDan Gohman <sunfish@google.com>
Tue, 26 Nov 2013 11:22:58 -0800
changeset 157592 9866d2a831a2a578b95b1439c2611b500acfbcf1
parent 157591 bc2c62619a12df93c2b7e6ba8ea939335af39d59
child 157593 ea3d28db82526fb0aec04342ab147bf1aef8eefb
push id25716
push userkwierso@gmail.com
push dateWed, 27 Nov 2013 01:32:11 +0000
treeherdermozilla-central@d822990ba9ee [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs943425
milestone28.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 943425 - IonMonkey: Avoid creating unused LMoveGroups. r=bhackett
js/src/jit/BacktrackingAllocator.cpp
js/src/jit/IonAnalysis.cpp
js/src/jit/LinearScan.cpp
js/src/jit/LiveRangeAllocator.h
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -949,18 +949,17 @@ BacktrackingAllocator::resolveControlFlo
             for (size_t k = 0; k < mSuccessor->numPredecessors(); k++) {
                 LBlock *predecessor = mSuccessor->getPredecessor(k)->lir();
                 JS_ASSERT(predecessor->mir()->numSuccessors() == 1);
 
                 LAllocation *input = phi->getOperand(predecessor->mir()->positionInPhiSuccessor());
                 LiveInterval *from = vregs[input].intervalFor(outputOf(predecessor->lastId()));
                 JS_ASSERT(from);
 
-                LMoveGroup *moves = predecessor->getExitMoveGroup(alloc());
-                if (!addMove(moves, from, to))
+                if (!moveAtExit(predecessor, from, to))
                     return false;
             }
         }
 
         // Resolve split intervals with moves
         BitSet *live = liveIn[mSuccessor->id()];
 
         for (BitSet::Iterator liveRegId(*live); liveRegId; liveRegId++) {
@@ -975,22 +974,20 @@ BacktrackingAllocator::resolveControlFlo
                         continue;
                     if (to->covers(outputOf(predecessor->lastId())))
                         continue;
 
                     LiveInterval *from = reg.intervalFor(outputOf(predecessor->lastId()));
 
                     if (mSuccessor->numPredecessors() > 1) {
                         JS_ASSERT(predecessor->mir()->numSuccessors() == 1);
-                        LMoveGroup *moves = predecessor->getExitMoveGroup(alloc());
-                        if (!addMove(moves, from, to))
+                        if (!moveAtExit(predecessor, from, to))
                             return false;
                     } else {
-                        LMoveGroup *moves = successor->getEntryMoveGroup(alloc());
-                        if (!addMove(moves, from, to))
+                        if (!moveAtEntry(successor, from, to))
                             return false;
                     }
                 }
             }
         }
     }
 
     return true;
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -1742,19 +1742,16 @@ jit::EliminateRedundantChecks(MIRGraph &
 // return the goto. Return nullptr otherwise.
 static LGoto *
 FindLeadingGoto(LBlock *bb)
 {
     for (LInstructionIterator ins(bb->begin()); ins != bb->end(); ins++) {
         // Ignore labels.
         if (ins->isLabel())
             continue;
-        // Ignore empty move groups.
-        if (ins->isMoveGroup() && ins->toMoveGroup()->numMoves() == 0)
-            continue;
         // If we have a goto, we're good to go.
         if (ins->isGoto())
             return ins->toGoto();
         break;
     }
     return nullptr;
 }
 
--- a/js/src/jit/LinearScan.cpp
+++ b/js/src/jit/LinearScan.cpp
@@ -240,18 +240,17 @@ LinearScanAllocator::resolveControlFlow(
             for (size_t k = 0; k < mSuccessor->numPredecessors(); k++) {
                 LBlock *predecessor = mSuccessor->getPredecessor(k)->lir();
                 JS_ASSERT(predecessor->mir()->numSuccessors() == 1);
 
                 LAllocation *input = phi->getOperand(predecessor->mir()->positionInPhiSuccessor());
                 LiveInterval *from = vregs[input].intervalFor(outputOf(predecessor->lastId()));
                 JS_ASSERT(from);
 
-                LMoveGroup *moves = predecessor->getExitMoveGroup(alloc());
-                if (!addMove(moves, from, to))
+                if (!moveAtExit(predecessor, from, to))
                     return false;
             }
 
             if (vreg->mustSpillAtDefinition() && !to->isSpill()) {
                 // Make sure this phi is spilled at the loop header.
                 LMoveGroup *moves = successor->getEntryMoveGroup(alloc());
                 if (!moves->add(to->getAllocation(), vregs[to->vreg()].canonicalSpill()))
                     return false;
@@ -279,22 +278,20 @@ LinearScanAllocator::resolveControlFlow(
                 if (vreg->mustSpillAtDefinition() && to->getAllocation()->isStackSlot()) {
                     JS_ASSERT(vreg->canonicalSpill());
                     JS_ASSERT(*vreg->canonicalSpill() == *to->getAllocation());
                     continue;
                 }
 
                 if (mSuccessor->numPredecessors() > 1) {
                     JS_ASSERT(predecessor->mir()->numSuccessors() == 1);
-                    LMoveGroup *moves = predecessor->getExitMoveGroup(alloc());
-                    if (!addMove(moves, from, to))
+                    if (!moveAtExit(predecessor, from, to))
                         return false;
                 } else {
-                    LMoveGroup *moves = successor->getEntryMoveGroup(alloc());
-                    if (!addMove(moves, from, to))
+                    if (!moveAtEntry(successor, from, to))
                         return false;
                 }
             }
         }
     }
 
     return true;
 }
--- a/js/src/jit/LiveRangeAllocator.h
+++ b/js/src/jit/LiveRangeAllocator.h
@@ -626,31 +626,48 @@ class LiveRangeAllocator : public Regist
         signed offset = OffsetToOtherHalfOfNunbox(vreg->type());
         VREG *other = &vregs[vreg->def()->virtualRegister() + offset];
         AssertTypesFormANunbox(vreg->type(), other->type());
         return other;
     }
 #endif
 
     bool addMove(LMoveGroup *moves, LiveInterval *from, LiveInterval *to) {
-        if (*from->getAllocation() == *to->getAllocation())
-            return true;
+        JS_ASSERT(*from->getAllocation() != *to->getAllocation());
         return moves->add(from->getAllocation(), to->getAllocation());
     }
 
     bool moveInput(CodePosition pos, LiveInterval *from, LiveInterval *to) {
+        if (*from->getAllocation() == *to->getAllocation())
+            return true;
         LMoveGroup *moves = getInputMoveGroup(pos);
         return addMove(moves, from, to);
     }
 
     bool moveAfter(CodePosition pos, LiveInterval *from, LiveInterval *to) {
+        if (*from->getAllocation() == *to->getAllocation())
+            return true;
         LMoveGroup *moves = getMoveGroupAfter(pos);
         return addMove(moves, from, to);
     }
 
+    bool moveAtExit(LBlock *block, LiveInterval *from, LiveInterval *to) {
+        if (*from->getAllocation() == *to->getAllocation())
+            return true;
+        LMoveGroup *moves = block->getExitMoveGroup(alloc());
+        return addMove(moves, from, to);
+    }
+
+    bool moveAtEntry(LBlock *block, LiveInterval *from, LiveInterval *to) {
+        if (*from->getAllocation() == *to->getAllocation())
+            return true;
+        LMoveGroup *moves = block->getEntryMoveGroup(alloc());
+        return addMove(moves, from, to);
+    }
+
     size_t findFirstNonCallSafepoint(CodePosition from) const
     {
         size_t i = 0;
         for (; i < graph.numNonCallSafepoints(); i++) {
             const LInstruction *ins = graph.getNonCallSafepoint(i);
             if (from <= inputOf(ins))
                 break;
         }