Bug 1135039: Implement LVariadicInstruction; r=sunfish
authorBenjamin Bouvier <benj@benj.me>
Thu, 12 Mar 2015 14:01:29 +0100
changeset 252059 12c2f0b35afed34eed6c632dfc3cb0678b7218fb
parent 252058 5dcff2ab60e65cfed5a1dd4856444cfedfbf7574
child 252060 bcad11e292db400d298c4732793c6580e7ece25d
push id1174
push usernsm.nikhil@gmail.com
push dateSun, 22 Mar 2015 01:24:25 +0000
reviewerssunfish
bugs1135039
milestone39.0a1
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);