Bug 1135039: Implement LVariadicInstruction; r=sunfish
authorBenjamin Bouvier <benj@benj.me>
Thu, 12 Mar 2015 14:01:29 +0100
changeset 263607 12c2f0b35afed34eed6c632dfc3cb0678b7218fb
parent 263606 5dcff2ab60e65cfed5a1dd4856444cfedfbf7574
child 263608 bcad11e292db400d298c4732793c6580e7ece25d
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs1135039
milestone39.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 1135039: Implement LVariadicInstruction; r=sunfish
js/src/jit/LIR.h
js/src/jit/shared/Lowering-shared-inl.h
js/src/jit/shared/Lowering-shared.h
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -8,16 +8,17 @@
 #define jit_LIR_h
 
 // This file declares the core data structures for LIR: storage allocations for
 // inputs and outputs, as well as the interface instructions must conform to.
 
 #include "mozilla/Array.h"
 
 #include "jit/Bailouts.h"
+#include "jit/FixedList.h"
 #include "jit/InlineList.h"
 #include "jit/JitAllocPolicy.h"
 #include "jit/LOpcodes.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 #include "jit/Registers.h"
 #include "jit/Safepoints.h"
 
@@ -1057,16 +1058,75 @@ class LInstructionHelper : public LInstr
         return getOperand(0);
     }
     const LDefinition *output() {
         MOZ_ASSERT(numDefs() == 1);
         return getDef(0);
     }
 };
 
+template<size_t Defs, size_t Temps>
+class LVariadicInstruction : public LInstruction
+{
+    mozilla::Array<LDefinition, Defs> defs_;
+    FixedList<LAllocation> operands_;
+    mozilla::Array<LDefinition, Temps> temps_;
+
+  public:
+    bool init(TempAllocator &alloc, size_t length) {
+        return operands_.init(alloc, length);
+    }
+
+    size_t numDefs() const MOZ_FINAL MOZ_OVERRIDE {
+        return Defs;
+    }
+    LDefinition *getDef(size_t index) MOZ_FINAL MOZ_OVERRIDE {
+        return &defs_[index];
+    }
+    size_t numOperands() const MOZ_FINAL MOZ_OVERRIDE {
+        return operands_.length();
+    }
+    LAllocation *getOperand(size_t index) MOZ_FINAL MOZ_OVERRIDE {
+        return &operands_[index];
+    }
+    size_t numTemps() const MOZ_FINAL MOZ_OVERRIDE {
+        return Temps;
+    }
+    LDefinition *getTemp(size_t index) MOZ_FINAL MOZ_OVERRIDE {
+        return &temps_[index];
+    }
+
+    void setDef(size_t index, const LDefinition &def) MOZ_FINAL MOZ_OVERRIDE {
+        defs_[index] = def;
+    }
+    void setOperand(size_t index, const LAllocation &a) MOZ_FINAL MOZ_OVERRIDE {
+        operands_[index] = a;
+    }
+    void setTemp(size_t index, const LDefinition &a) MOZ_FINAL MOZ_OVERRIDE {
+        temps_[index] = a;
+    }
+
+    size_t numSuccessors() const MOZ_OVERRIDE {
+        return 0;
+    }
+    MBasicBlock *getSuccessor(size_t i) const MOZ_OVERRIDE {
+        MOZ_ASSERT(false);
+        return nullptr;
+    }
+    void setSuccessor(size_t i, MBasicBlock *successor) MOZ_OVERRIDE {
+        MOZ_ASSERT(false);
+    }
+
+    // Default accessors, assuming a single input and output, respectively.
+    const LDefinition *output() {
+        MOZ_ASSERT(numDefs() == 1);
+        return getDef(0);
+    }
+};
+
 template <size_t Defs, size_t Operands, size_t Temps>
 class LCallInstructionHelper : public LInstructionHelper<Defs, Operands, Temps>
 {
   public:
     virtual bool isCall() const {
         return true;
     }
 };
--- a/js/src/jit/shared/Lowering-shared-inl.h
+++ b/js/src/jit/shared/Lowering-shared-inl.h
@@ -30,16 +30,40 @@ LIRGeneratorShared::use(MDefinition *mir
 #if BOX_PIECES > 1
     MOZ_ASSERT(mir->type() != MIRType_Value);
 #endif
     ensureDefined(mir);
     policy.setVirtualRegister(mir->virtualRegister());
     return policy;
 }
 
+template <size_t X> void
+LIRGeneratorShared::define(LVariadicInstruction<1, X> *lir, MDefinition *mir, const LDefinition &def)
+{
+    // Call instructions should use defineReturn.
+    MOZ_ASSERT(!lir->isCall());
+
+    uint32_t vreg = getVirtualRegister();
+
+    // Assign the definition and a virtual register. Then, propagate this
+    // virtual register to the MIR, so we can map MIR to LIR during lowering.
+    lir->setDef(0, def);
+    lir->getDef(0)->setVirtualRegister(vreg);
+    lir->setMir(mir);
+    mir->setVirtualRegister(vreg);
+    add(lir);
+}
+
+template <size_t X> void
+LIRGeneratorShared::define(LVariadicInstruction<1, X> *lir, MDefinition *mir, LDefinition::Policy policy)
+{
+    LDefinition::Type type = LDefinition::TypeFrom(mir->type());
+    define(lir, mir, LDefinition(type, policy));
+}
+
 template <size_t X, size_t Y> void
 LIRGeneratorShared::define(LInstructionHelper<1, X, Y> *lir, MDefinition *mir, const LDefinition &def)
 {
     // Call instructions should use defineReturn.
     MOZ_ASSERT(!lir->isCall());
 
     uint32_t vreg = getVirtualRegister();
 
--- a/js/src/jit/shared/Lowering-shared.h
+++ b/js/src/jit/shared/Lowering-shared.h
@@ -140,16 +140,23 @@ class LIRGeneratorShared : public MDefin
                             const LAllocation &output);
 
     template <size_t Ops, size_t Temps>
     inline void defineBox(LInstructionHelper<BOX_PIECES, Ops, Temps> *lir, MDefinition *mir,
                           LDefinition::Policy policy = LDefinition::REGISTER);
 
     inline void defineReturn(LInstruction *lir, MDefinition *mir);
 
+    template <size_t X>
+    inline void define(LVariadicInstruction<1, X> *lir, MDefinition *mir, const LDefinition &def);
+
+    template <size_t X>
+    inline void define(LVariadicInstruction<1, X> *lir, MDefinition *mir,
+                       LDefinition::Policy policy = LDefinition::REGISTER);
+
     template <size_t Ops, size_t Temps>
     inline void define(LInstructionHelper<1, Ops, Temps> *lir, MDefinition *mir,
                         const LDefinition &def);
 
     template <size_t Ops, size_t Temps>
     inline void define(LInstructionHelper<1, Ops, Temps> *lir, MDefinition *mir,
                        LDefinition::Policy policy = LDefinition::REGISTER);