Bug 934502 - Group entry and OSR values for parameters in backtracking allocator, allow backtracking allocator to spill vregs to argument slots, r=sunfish.
authorBrian Hackett <bhackett1024@gmail.com>
Sun, 25 Jan 2015 17:17:43 -0700
changeset 225636 61f7a945aea010af9bb6fb2f045c73186283bd66
parent 225635 1a349b0fd0089f23a62cf2bcfdb9596ea1a25bd4
child 225637 6ae46792bd9cb33326262f13d6c9b2fcce9efa9b
push id10990
push usercbook@mozilla.com
push dateMon, 26 Jan 2015 14:06:38 +0000
treeherderfx-team@54be9bcdacd9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs934502
milestone38.0a1
Bug 934502 - Group entry and OSR values for parameters in backtracking allocator, allow backtracking allocator to spill vregs to argument slots, r=sunfish.
js/src/jit/BacktrackingAllocator.cpp
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -307,16 +307,41 @@ BacktrackingAllocator::tryGroupReusedReg
     usedReg.setCanonicalSpillExclude(inputOf(reg.ins()));
 
     return tryGroupRegisters(use, def);
 }
 
 bool
 BacktrackingAllocator::groupAndQueueRegisters()
 {
+    // If there is an OSR block, group parameters in that block with the
+    // corresponding parameters in the initial block.
+    if (MBasicBlock *osr = graph.mir().osrBlock()) {
+        size_t originalVreg = 1;
+        for (LInstructionIterator iter = osr->lir()->begin(); iter != osr->lir()->end(); iter++) {
+            if (iter->isParameter()) {
+                for (size_t i = 0; i < iter->numDefs(); i++) {
+                    DebugOnly<bool> found = false;
+                    uint32_t paramVreg = iter->getDef(i)->virtualRegister();
+                    for (; originalVreg < paramVreg; originalVreg++) {
+                        if (*vregs[originalVreg].def()->output() == *iter->getDef(i)->output()) {
+                            MOZ_ASSERT(vregs[originalVreg].ins()->isParameter());
+                            if (!tryGroupRegisters(originalVreg, paramVreg))
+                                return false;
+                            MOZ_ASSERT(vregs[originalVreg].group() == vregs[paramVreg].group());
+                            found = true;
+                            break;
+                        }
+                    }
+                    MOZ_ASSERT(found);
+                }
+            }
+        }
+    }
+
     // Try to group registers with their reused inputs.
     // Virtual register number 0 is unused.
     MOZ_ASSERT(vregs[0u].numIntervals() == 0);
     for (size_t i = 1; i < graph.numVirtualRegisters(); i++) {
         BacktrackingVirtualRegister &reg = vregs[i];
         if (!reg.numIntervals())
             continue;
 
@@ -349,27 +374,24 @@ BacktrackingAllocator::groupAndQueueRegi
 
         BacktrackingVirtualRegister &reg = vregs[i];
         MOZ_ASSERT(reg.numIntervals() <= 2);
         MOZ_ASSERT(!reg.canonicalSpill());
 
         if (!reg.numIntervals())
             continue;
 
-        // Disable this for now; see bugs 906858, 931487, and 932465.
-#if 0
         // Eagerly set the canonical spill slot for registers which are fixed
         // for that slot, and reuse it for other registers in the group.
         LDefinition *def = reg.def();
         if (def->policy() == LDefinition::FIXED && !def->output()->isRegister()) {
             reg.setCanonicalSpill(*def->output());
             if (reg.group() && reg.group()->spill.isUse())
                 reg.group()->spill = *def->output();
         }
-#endif
 
         // Place all intervals for this register on the allocation queue.
         // During initial queueing use single queue items for groups of
         // registers, so that they will be allocated together and reduce the
         // risk of unnecessary conflicts. This is in keeping with the idea that
         // register groups are effectively single registers whose value changes
         // during execution. If any intervals in the group are evicted later
         // then they will be reallocated individually.