Bug 1020455 - IonMonkey: Optimize LPhi allocation r=sstangl
authorDan Gohman <sunfish@mozilla.com>
Wed, 04 Jun 2014 14:08:22 -0700
changeset 206991 daae873f90b3252b46426170311921e1e3edfc1c
parent 206990 81a81052fe9ff567318a6d79c270c6f5d350f85d
child 206992 a76d3c8b0f6421112bdb0516108d0651526b3d0e
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssstangl
bugs1020455
milestone32.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 1020455 - IonMonkey: Optimize LPhi allocation r=sstangl
js/src/jit/LIR-Common.h
js/src/jit/LIR.cpp
js/src/jit/LIR.h
js/src/jit/Lowering.cpp
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -5576,26 +5576,27 @@ class LGuardClass : public LInstructionH
 class MPhi;
 
 // Phi is a pseudo-instruction that emits no code, and is an annotation for the
 // register allocator. Like its equivalent in MIR, phis are collected at the
 // top of blocks and are meant to be executed in parallel, choosing the input
 // corresponding to the predecessor taken in the control flow graph.
 class LPhi MOZ_FINAL : public LInstruction
 {
-    LAllocation *inputs_;
+    LAllocation *const inputs_;
     LDefinition def_;
 
-    LPhi()
-    { }
-
   public:
     LIR_HEADER(Phi)
 
-    static LPhi *New(MIRGenerator *gen, MPhi *phi);
+    LPhi(MPhi *ins, LAllocation *inputs)
+        : inputs_(inputs)
+    {
+        setMir(ins);
+    }
 
     size_t numDefs() const {
         return 1;
     }
     LDefinition *getDef(size_t index) {
         JS_ASSERT(index == 0);
         return &def_;
     }
--- a/js/src/jit/LIR.cpp
+++ b/js/src/jit/LIR.cpp
@@ -81,24 +81,46 @@ LBlock::New(TempAllocator &alloc, MBasic
     // Count the number of LPhis we'll need.
     size_t numLPhis = 0;
     for (MPhiIterator i(from->phisBegin()), e(from->phisEnd()); i != e; ++i) {
         MPhi *phi = *i;
         numLPhis += (phi->type() == MIRType_Value) ? BOX_PIECES : 1;
     }
 
     // Allocate space for the LPhis.
-    return block->phis_.init(alloc, numLPhis) ? block : nullptr;
+    if (!block->phis_.init(alloc, numLPhis))
+        return nullptr;
+
+    // For each MIR phi, set up LIR phis as appropriate. We'll fill in their
+    // operands on each incoming edge, and set their definitions at the start of
+    // their defining block.
+    size_t phiIndex = 0;
+    size_t numPreds = from->numPredecessors();
+    for (MPhiIterator i(from->phisBegin()), e(from->phisEnd()); i != e; ++i) {
+        MPhi *phi = *i;
+        MOZ_ASSERT(phi->numOperands() == numPreds);
+
+        int numPhis = (phi->type() == MIRType_Value) ? BOX_PIECES : 1;
+        for (int i = 0; i < numPhis; i++) {
+            void *array = alloc.allocateArray<sizeof(LAllocation)>(numPreds);
+            LAllocation *inputs = static_cast<LAllocation *>(array);
+            if (!inputs)
+                return nullptr;
+
+            new (&block->phis_[phiIndex++]) LPhi(phi, inputs);
+        }
+    }
+    return block;
 }
 
 uint32_t
 LBlock::firstId()
 {
     if (phis_.length()) {
-        return phis_[0]->id();
+        return phis_[0].id();
     } else {
         for (LInstructionIterator i(instructions_.begin()); i != instructions_.end(); i++) {
             if (i->id())
                 return i->id();
         }
     }
     return 0;
 }
@@ -282,29 +304,16 @@ LSnapshot::rewriteRecoveredInput(LUse in
     // Mark any operands to this snapshot with the same value as input as being
     // equal to the instruction's result.
     for (size_t i = 0; i < numEntries(); i++) {
         if (getEntry(i)->isUse() && getEntry(i)->toUse()->virtualRegister() == input.virtualRegister())
             setEntry(i, LUse(input.virtualRegister(), LUse::RECOVERED_INPUT));
     }
 }
 
-LPhi *
-LPhi::New(MIRGenerator *gen, MPhi *ins)
-{
-    LPhi *phi = new (gen->alloc()) LPhi();
-    LAllocation *inputs = gen->allocate<LAllocation>(ins->numOperands());
-    if (!inputs)
-        return nullptr;
-
-    phi->inputs_ = inputs;
-    phi->setMir(ins);
-    return phi;
-}
-
 void
 LInstruction::printName(FILE *fp, Opcode op)
 {
     static const char * const names[] =
     {
 #define LIROP(x) #x,
         LIR_OPCODE_LIST(LIROP)
 #undef LIROP
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -724,17 +724,17 @@ class LInstructionVisitor
 typedef InlineList<LInstruction>::iterator LInstructionIterator;
 typedef InlineList<LInstruction>::reverse_iterator LInstructionReverseIterator;
 
 class LPhi;
 class LMoveGroup;
 class LBlock : public TempObject
 {
     MBasicBlock *block_;
-    FixedList<LPhi *> phis_;
+    FixedList<LPhi> phis_;
     InlineList<LInstruction> instructions_;
     LMoveGroup *entryMoveGroup_;
     LMoveGroup *exitMoveGroup_;
     Label label_;
 
     explicit LBlock(MBasicBlock *block)
       : block_(block),
         phis_(),
@@ -742,24 +742,21 @@ class LBlock : public TempObject
         exitMoveGroup_(nullptr)
     { }
 
   public:
     static LBlock *New(TempAllocator &alloc, MBasicBlock *from);
     void add(LInstruction *ins) {
         instructions_.pushBack(ins);
     }
-    void setPhi(size_t index, LPhi *phi) {
-        phis_[index] = phi;
-    }
     size_t numPhis() const {
         return phis_.length();
     }
-    LPhi *getPhi(size_t index) const {
-        return phis_[index];
+    LPhi *getPhi(size_t index) {
+        return &phis_[index];
     }
     MBasicBlock *mir() const {
         return block_;
     }
     LInstructionIterator begin() {
         return instructions_.begin();
     }
     LInstructionIterator begin(LInstruction *at) {
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -3724,30 +3724,16 @@ LIRGenerator::generate()
         if (gen->shouldCancel("Lowering (preparation loop)"))
             return false;
 
         current = LBlock::New(alloc(), *block);
         if (!current)
             return false;
         lirGraph_.setBlock(block->id(), current);
         block->assignLir(current);
-
-        // For each MIR phi, add LIR phis as appropriate. We'll fill in their
-        // operands on each incoming edge, and set their definitions at the
-        // start of their defining block.
-        size_t phiIndex = 0;
-        for (MPhiIterator phi(block->phisBegin()); phi != block->phisEnd(); phi++) {
-            int numPhis = (phi->type() == MIRType_Value) ? BOX_PIECES : 1;
-            for (int i = 0; i < numPhis; i++) {
-                LPhi *lir = LPhi::New(gen, *phi);
-                if (!lir)
-                    return false;
-                block->lir()->setPhi(phiIndex++, lir);
-            }
-        }
     }
 
     for (ReversePostorderIterator block(graph.rpoBegin()); block != graph.rpoEnd(); block++) {
         if (gen->shouldCancel("Lowering (main loop)"))
             return false;
 
         if (!visitBlock(*block))
             return false;