ebo avatar ebo committed 8a07a20

added more type feedback

Comments (0)

Files changed (1)

 diff --git a/JIT/global_jit_data.h b/JIT/global_jit_data.h
 --- a/JIT/global_jit_data.h
 +++ b/JIT/global_jit_data.h
-@@ -114,11 +114,15 @@
+@@ -91,6 +91,8 @@
+ 
+   void unsuspend()
+   {
++    assert(PyThreadState_GET()->interp != NULL);
++    assert(PyThreadState_GET()->interp->global_jit_data != NULL);
+     suspended_ = false;
+     trace_.clear();
+   }
+@@ -105,6 +107,8 @@
+   {
      if (!active_ || suspended_)
        return;
++    if (trace_.size() == 0)
++      return;
+     TraceEntry &entry = trace_.back();
+     entry.flag = flag;
+   }
+@@ -113,12 +117,19 @@
+   {
+     if (!active_ || suspended_)
+       return;
++    if (trace_.size() == 0) {
++      return;
++    }
      TraceEntry &entry = trace_.back();
 -    if (pos == 0) {
 +    switch (pos) {
 new file mode 100644
 --- /dev/null
 +++ b/JIT/jit_binop.cc
-@@ -0,0 +1,75 @@
+@@ -0,0 +1,277 @@
 +#include "JIT/jit_binop.h"
 +#include "JIT/jit_types.h"
 +#include "JIT/jit_tracer.h"
 +
++#include "Python.h"
++#include "opcode.h"
++
 +using llvm::Value;
 +
 +namespace jit {
 +  };
 +
 +
++  class BinarySubtractImpl : public BinaryOpImpl {
++  public:
++    BinarySubtractImpl(JITValue *arg0, JITValue *arg1)
++      : arg0_(arg0), arg1_(arg1), float_inline_(false)
++    {
++      if (arg0_->getStaticType()->isFloat() && arg1_->getStaticType()->isFloat()) {
++        float_inline_ = true;
++      }
++    }
++
++    virtual bool inlined() const
++    {
++      return float_inline_;
++    }
++
++    virtual void emit_inline(JITFunctionBuilder &fbuilder, JITType *result)
++    {
++      JITFunctionState::BuilderT &builder = fbuilder.builder();
++      JITFunctionState *state = fbuilder.getState();
++
++      Value *naked0 = arg0_->getStaticType()->getNakedValue(fbuilder);
++      Value *naked1 = arg1_->getStaticType()->getNakedValue(fbuilder);
++      Value *naked_result = builder.CreateFSub(naked0, naked1);
++
++      Value *func = state->GetGlobalFunction<PyObject*(double)>("PyFloat_FromDouble");
++      Value *value = state->CreateCall(func, naked_result);
++      result->init(value);
++    }
++
++    virtual void emit_inplace_inline(JITFunctionBuilder &fbuilder, JITType *result)
++    {
++      this->emit_inline(fbuilder, result);
++    }
++
++    virtual void emit(JITFunctionBuilder &fbuilder, JITType *result)
++    {
++      JITFunctionState *state = fbuilder.getState();
++      Value *func = state->GetGlobalFunction<PyObject*(PyObject*, PyObject*)>("PyNumber_Subtract");
++      llvm::Value *value = state->CreateCall(func,
++                                             arg0_->getValue(),
++                                             arg1_->getValue());
++      result->init(value);
++    }
++
++    virtual void emit_inplace(JITFunctionBuilder &fbuilder, JITType *result)
++    {
++      JITFunctionState *state = fbuilder.getState();
++      Value *func = state->GetGlobalFunction<PyObject*(PyObject*, PyObject*)>("PyNumber_InPlaceSubtract");
++      llvm::Value *value = state->CreateCall(func,
++                                             arg0_->getValue(),
++                                             arg1_->getValue());
++      result->init(value);
++    }
++
++  private:
++    JITValue *arg0_;
++    JITValue *arg1_;
++    bool float_inline_;
++  };
++
++  class BinaryMultiplyImpl : public BinaryOpImpl {
++  public:
++    BinaryMultiplyImpl(JITValue *arg0, JITValue *arg1)
++      : arg0_(arg0), arg1_(arg1), float_inline_(false)
++    {
++      if (arg0_->getStaticType()->isFloat() && arg1_->getStaticType()->isFloat()) {
++        float_inline_ = true;
++      }
++    }
++
++    virtual bool inlined() const
++    {
++      return float_inline_;
++    }
++
++    virtual void emit_inline(JITFunctionBuilder &fbuilder, JITType *result)
++    {
++      JITFunctionState::BuilderT &builder = fbuilder.builder();
++      JITFunctionState *state = fbuilder.getState();
++
++      Value *naked0 = arg0_->getStaticType()->getNakedValue(fbuilder);
++      Value *naked1 = arg1_->getStaticType()->getNakedValue(fbuilder);
++      Value *naked_result = builder.CreateFMul(naked0, naked1);
++
++      Value *func = state->GetGlobalFunction<PyObject*(double)>("PyFloat_FromDouble");
++      Value *value = state->CreateCall(func, naked_result);
++      result->init(value);
++    }
++
++    virtual void emit_inplace_inline(JITFunctionBuilder &fbuilder, JITType *result)
++    {
++      this->emit_inline(fbuilder, result);
++    }
++
++    virtual void emit(JITFunctionBuilder &fbuilder, JITType *result)
++    {
++      JITFunctionState *state = fbuilder.getState();
++      Value *func = state->GetGlobalFunction<PyObject*(PyObject*, PyObject*)>("PyNumber_Multiply");
++      llvm::Value *value = state->CreateCall(func,
++                                             arg0_->getValue(),
++                                             arg1_->getValue());
++      result->init(value);
++    }
++
++    virtual void emit_inplace(JITFunctionBuilder &fbuilder, JITType *result)
++    {
++      JITFunctionState *state = fbuilder.getState();
++      Value *func = state->GetGlobalFunction<PyObject*(PyObject*, PyObject*)>("PyNumber_InPlaceMultiply");
++      llvm::Value *value = state->CreateCall(func,
++                                             arg0_->getValue(),
++                                             arg1_->getValue());
++      result->init(value);
++    }
++
++  private:
++    JITValue *arg0_;
++    JITValue *arg1_;
++    bool float_inline_;
++  };
++
++  class BinaryDivideImpl : public BinaryOpImpl {
++  public:
++    BinaryDivideImpl(JITValue *arg0, JITValue *arg1)
++      : arg0_(arg0), arg1_(arg1), float_inline_(false)
++    {
++      if (arg0_->getStaticType()->isFloat() && arg1_->getStaticType()->isFloat()) {
++        float_inline_ = true;
++      }
++    }
++
++    virtual bool inlined() const
++    {
++      return float_inline_;
++    }
++
++    virtual void emit_inline(JITFunctionBuilder &fbuilder, JITType *result)
++    {
++      JITFunctionState::BuilderT &builder = fbuilder.builder();
++      JITFunctionState *state = fbuilder.getState();
++
++      Value *naked0 = arg0_->getStaticType()->getNakedValue(fbuilder);
++      Value *naked1 = arg1_->getStaticType()->getNakedValue(fbuilder);
++      Value *naked_result = builder.CreateFDiv(naked0, naked1);
++
++      Value *func = state->GetGlobalFunction<PyObject*(double)>("PyFloat_FromDouble");
++      Value *value = state->CreateCall(func, naked_result);
++      result->init(value);
++    }
++
++    virtual void emit_inplace_inline(JITFunctionBuilder &fbuilder, JITType *result)
++    {
++      this->emit_inline(fbuilder, result);
++    }
++
++    virtual void emit(JITFunctionBuilder &fbuilder, JITType *result)
++    {
++      JITFunctionState *state = fbuilder.getState();
++      Value *func = state->GetGlobalFunction<PyObject*(PyObject*, PyObject*)>("PyNumber_FloorDivide");
++      llvm::Value *value = state->CreateCall(func,
++                                             arg0_->getValue(),
++                                             arg1_->getValue());
++      result->init(value);
++    }
++
++    virtual void emit_inplace(JITFunctionBuilder &fbuilder, JITType *result)
++    {
++      JITFunctionState *state = fbuilder.getState();
++      Value *func = state->GetGlobalFunction<PyObject*(PyObject*, PyObject*)>("PyNumber_InPlaceFloorDivide");
++      llvm::Value *value = state->CreateCall(func,
++                                             arg0_->getValue(),
++                                             arg1_->getValue());
++      result->init(value);
++    }
++
++  private:
++    JITValue *arg0_;
++    JITValue *arg1_;
++    bool float_inline_;
++  };
++
 +  BinaryOpImpl *BinaryOpImpl::create(int opcode, JITValue *arg0, JITValue *arg1)
 +  {
-+    return new BinaryAddImpl(arg0, arg1);
++    switch (opcode) {
++    case INPLACE_ADD:
++    case BINARY_ADD:
++      return new BinaryAddImpl(arg0, arg1);
++
++    case INPLACE_SUBTRACT:
++    case BINARY_SUBTRACT:
++      return new BinarySubtractImpl(arg0, arg1);
++
++    case INPLACE_MULTIPLY:
++    case BINARY_MULTIPLY:
++      return new BinaryMultiplyImpl(arg0, arg1);
++
++    case INPLACE_FLOOR_DIVIDE:
++    case BINARY_FLOOR_DIVIDE:
++      return new BinaryDivideImpl(arg0, arg1);
++    default:
++      break;
++    }
++    return NULL;
 +  }
 +
 +}
      int opcode = cut_trace[i].opcode;
      int oparg = cut_trace[i].oparg;
      int flag = cut_trace[i].flag;
-@@ -109,13 +109,14 @@
+@@ -82,8 +82,12 @@
+     case STORE_FAST:
+     case LOAD_FAST:
+     case LOAD_CONST:
++    case JUMP_ABSOLUTE:
++
+     case INPLACE_ADD:
+-    case JUMP_ABSOLUTE:
++    case INPLACE_SUBTRACT:
++    case INPLACE_MULTIPLY:
++    case INPLACE_FLOOR_DIVIDE:
+     case BINARY_ADD:
+     case BINARY_SUBTRACT:
+     case BINARY_MULTIPLY:
+@@ -109,13 +113,14 @@
        break;
  
      default:
      return;
    }
  
-@@ -144,7 +145,7 @@
+@@ -144,7 +149,7 @@
  
    jit::JITTraceAnalysis analysis;
    analysis.analyseTrace(cut_trace);
    jit::JITFunctionState state(PyGlobalJITData::Get());
    analysis.emit(state);
    PyGlobalJITData::Get()->optimize(state.function());
-@@ -160,7 +161,8 @@
+@@ -160,7 +165,8 @@
  }
  
  void
  {
    if (!active_)
      return;
-@@ -189,6 +191,36 @@
+@@ -189,6 +195,36 @@
  
  namespace jit {
  
    JITTraceAnalysis::JITTraceAnalysis()
      : stack_counter_(0)
    {
-@@ -206,37 +238,55 @@
+@@ -206,37 +242,50 @@
      }
    }
  
 -  JITValue *
 -  JITTraceAnalysis::Pop()
-+  static bool binop_needs_guards(int opcode, JITType *v, JITType *w)
++  void
++  JITTraceAnalysis::createBinaryOp(bool inplace, JITStack &stack, TraceEntry &entry)
    {
 -    if (stack_.size() > 0) {
 -      JITValue *v = stack_.back();
 -      stack_.pop_back();
 -      return v;
-+    switch(opcode) {
-+    case INPLACE_ADD:
-+      if (v->isFloat() && w->isFloat()) {
-+        return true;
-+      }
-     }
--
--    JITStackValue *v = new JITStackValue;
--    loaded_stack_.push_back(v);
--    return v;
--  }
--
--  JITValue *
--  JITTraceAnalysis::Top()
--  {
--    JITValue *v = this->Pop();
--    this->Push(v);
--    return v;
-+    return false;
-   }
- 
-   void
--  JITTraceAnalysis::Push(JITValue *value)
-+  JITTraceAnalysis::createBinaryOp(bool inplace, JITStack &stack, TraceEntry &entry)
-   {
--    stack_.push_back(value);
 +    int opcode = entry.opcode;
 +    JITValue *w = stack.Pop();
 +    JITValue *v = stack.Pop();
++    // std::cout << "binop "
++    //           << (entry.arg0 ? entry.arg0->tp_name : "NULL")
++    //           << " "
++    //           << (entry.arg1 ? entry.arg1->tp_name : "NULL")
++    //           << "\n";
 +    if (entry.arg0 != NULL)
 +      v->registerStaticType(entry.arg0);
 +    if (entry.arg1 != NULL)
 +      w->registerStaticType(entry.arg1);
 +
 +    BinaryOpImpl *impl = BinaryOpImpl::create(opcode, v, w);
++    assert(impl != NULL);
 +
 +    JITType *type_v = v->getStaticType();
 +    JITType *type_w = w->getStaticType();
 +        type_w->setGuard(true);
 +        this->createGuardType(w, BH_NO_BLACKHOLE, entry.pc, stack);
 +      }
-+    }
-+
+     }
+ 
+-    JITStackValue *v = new JITStackValue;
+-    loaded_stack_.push_back(v);
+-    return v;
+-  }
 +    JITValue *x = this->createGenericBinOp(impl, inplace, v, w);
-+
+ 
+-  JITValue *
+-  JITTraceAnalysis::Top()
+-  {
+-    JITValue *v = this->Pop();
+-    this->Push(v);
+-    return v;
+-  }
+-
+-  void
+-  JITTraceAnalysis::Push(JITValue *value)
+-  {
+-    stack_.push_back(value);
 +    assert(x != NULL);
 +    this->createGuardNull(x, BH_BINARY_OP_FAIL, entry.pc, stack);
 +    stack.Push(x);
      for (size_t i = 0; i < trace.size(); ++i) {
        TraceEntry &entry = trace[i];
        int opcode = entry.opcode;
-@@ -249,94 +299,72 @@
+@@ -249,94 +298,79 @@
  
  
        case POP_JUMP_IF_FALSE:
 -        x = this->createInplaceAdd(v, w);
 -        this->createGuardNull(x, BH_INPLACE_ADD_FAIL, entry.pc);
 -        this->Push(x);
--        continue;
--
++      case INPLACE_SUBTRACT:
++      case INPLACE_MULTIPLY:
++      case INPLACE_FLOOR_DIVIDE:
 +        this->createBinaryOp(true, stack, entry);
 +        break;
-       case BINARY_ADD:
++
++      case BINARY_ADD:
++      case BINARY_SUBTRACT:
++      case BINARY_MULTIPLY:
++      case BINARY_FLOOR_DIVIDE:
++        this->createBinaryOp(false, stack, entry);
++        break;
++
++      case COMPARE_OP:
++        w = stack.Pop();
++        v = stack.Pop();
++        if (entry.arg0 != NULL)
++          v->registerStaticType(entry.arg0);
++        if (entry.arg1 != NULL)
++          w->registerStaticType(entry.arg1);
++        x = this->createCompareOp(v, w, entry.oparg);
++        this->createGuardNull(x, BH_BINARY_OP_FAIL, entry.pc, stack);
++        stack.Push(x);
+         continue;
+ 
+-      case BINARY_ADD:
 -        w = this->Pop();
 -        v = this->Pop();
 -        x = this->createBinaryAdd(v, w);
 -        this->Push(x);
 -        continue;
 -
-       case BINARY_SUBTRACT:
+-      case BINARY_SUBTRACT:
 -        w = this->Pop();
 -        v = this->Pop();
 -        x = this->createBinarySubtract(v, w);
 -        this->Push(x);
 -        continue;
 -
-       case BINARY_MULTIPLY:
+-      case BINARY_MULTIPLY:
 -        w = this->Pop();
 -        v = this->Pop();
 -        x = this->createBinaryMultiply(v, w);
 -        this->Push(x);
 -        continue;
 -
-       case BINARY_FLOOR_DIVIDE:
+-      case BINARY_FLOOR_DIVIDE:
 -        w = this->Pop();
 -        v = this->Pop();
 -        x = this->createBinaryDivide(v, w);
 -        this->createGuardNull(x, BH_BINARY_OP_FAIL, entry.pc);
 -        this->Push(x);
 -        continue;
-+        this->createBinaryOp(false, stack, entry);
-+        break;
- 
-       case COMPARE_OP:
+-
+-      case COMPARE_OP:
 -        w = this->Pop();
 -        v = this->Pop();
-+        w = stack.Pop();
-+        v = stack.Pop();
-+        if (entry.arg0 != NULL)
-+          v->registerStaticType(entry.arg0);
-+        if (entry.arg1 != NULL)
-+          w->registerStaticType(entry.arg1);
-         x = this->createCompareOp(v, w, entry.oparg);
+-        x = this->createCompareOp(v, w, entry.oparg);
 -        this->createGuardNull(x, BH_BINARY_OP_FAIL, entry.pc);
 -        this->Push(x);
-+        this->createGuardNull(x, BH_BINARY_OP_FAIL, entry.pc, stack);
-+        stack.Push(x);
-         continue;
+-        continue;
++      default:
++        assert(false);
        }
      }
 -    this->createTraceEnd();
    }
  
    void
-@@ -351,6 +379,7 @@
+@@ -351,6 +385,7 @@
                           "tp_iternext");
  
      value_ = fbuilder.getState()->CreateCall(tp_iternext, v);
    }
  
    void
-@@ -370,6 +399,7 @@
+@@ -370,6 +405,7 @@
      JITFunctionState::BuilderT &builder = fbuilder.builder();
      llvm::Value *localptr = fbuilder.LocalPtr(oparg_);
      value_ = builder.CreateLoad(localptr);
    }
  
    void
-@@ -378,12 +408,33 @@
+@@ -378,69 +414,32 @@
      JITFunctionState::BuilderT &builder = fbuilder.builder();
      llvm::Value *localptr = fbuilder.ConstPtr(oparg_);
      value_ = builder.CreateLoad(localptr);
 +    this->getStaticType()->init(value_);
-   }
- 
-   void
-   JITInplaceAdd::emit(JITFunctionBuilder &fbuilder)
-   {
-     JITFunctionState *state = fbuilder.getState();
-+    JITFunctionState::BuilderT &builder = fbuilder.builder();
-+
-+    if (this->float_inline_) {
-+
-+      JITType *type0 = arg0_->getStaticType();
-+      JITType *type1 = arg1_->getStaticType();
-+
-+      Value *naked0 = type0->getNakedValue(fbuilder);
-+      Value *naked1 = type1->getNakedValue(fbuilder);
-+
-+      state->DecRef(arg0_->getValue());
-+      state->DecRef(arg1_->getValue());
-+
-+      Value *result = builder.CreateFAdd(naked0, naked1);
-+
-+      Value *func = state->GetGlobalFunction<PyObject*(double)>("PyFloat_FromDouble");
-+      value_ = state->CreateCall(func, result);
-+      this->getStaticType()->init(value_);
-+      return;
-+    }
- 
-     Value *func = state->GetGlobalFunction<PyObject*(PyObject*, PyObject*)>("PyNumber_InPlaceAdd");
-     value_ = state->CreateCall(func,
-@@ -391,6 +442,34 @@
-                                arg1_->getValue());
-     state->DecRef(arg0_->getValue());
-     state->DecRef(arg1_->getValue());
-+    this->getStaticType()->init(value_);
 +  }
 +
 +  JITGenericBinOp::JITGenericBinOp(BinaryOpImpl *impl, bool inplace, JITValue *arg0, JITValue *arg1)
 +      type_(new JITOpaqueObject), impl_(impl),
 +      inplace_(inplace)
 +  {
-+  }
-+
-+  void
+   }
+ 
+   void
+-  JITInplaceAdd::emit(JITFunctionBuilder &fbuilder)
 +  JITGenericBinOp::emit(JITFunctionBuilder &fbuilder)
-+  {
-+    JITFunctionState *state = fbuilder.getState();
+   {
+     JITFunctionState *state = fbuilder.getState();
+-
+-    Value *func = state->GetGlobalFunction<PyObject*(PyObject*, PyObject*)>("PyNumber_InPlaceAdd");
+-    value_ = state->CreateCall(func,
+-                               arg0_->getValue(),
+-                               arg1_->getValue());
+-    state->DecRef(arg0_->getValue());
+-    state->DecRef(arg1_->getValue());
+-  }
+-
+-  void
+-  JITBinaryAdd::emit(JITFunctionBuilder &fbuilder)
+-  {
+-    JITFunctionState *state = fbuilder.getState();
+-
+-    Value *func = state->GetGlobalFunction<PyObject*(PyObject*, PyObject*)>("PyNumber_Add");
+-    value_ = state->CreateCall(func,
+-                               arg0_->getValue(),
+-                               arg1_->getValue());
+-    state->DecRef(arg0_->getValue());
+-    state->DecRef(arg1_->getValue());
+-  }
+-
+-  void
+-  JITBinarySubtract::emit(JITFunctionBuilder &fbuilder)
+-  {
+-    JITFunctionState *state = fbuilder.getState();
+-
+-    Value *func = state->GetGlobalFunction<PyObject*(PyObject*, PyObject*)>("PyNumber_Subtract");
+-    value_ = state->CreateCall(func,
+-                               arg0_->getValue(),
+-                               arg1_->getValue());
+-    state->DecRef(arg0_->getValue());
+-    state->DecRef(arg1_->getValue());
+-  }
+-
+-  void
+-  JITBinaryMultiply::emit(JITFunctionBuilder &fbuilder)
+-  {
+-    JITFunctionState *state = fbuilder.getState();
+-
+-    Value *func = state->GetGlobalFunction<PyObject*(PyObject*, PyObject*)>("PyNumber_Multiply");
+-    value_ = state->CreateCall(func,
+-                               arg0_->getValue(),
+-                               arg1_->getValue());
+-    state->DecRef(arg0_->getValue());
+-    state->DecRef(arg1_->getValue());
+-  }
+-
+-  void
+-  JITBinaryDivide::emit(JITFunctionBuilder &fbuilder)
+-  {
+-    JITFunctionState *state = fbuilder.getState();
+-
+-    Value *func = state->GetGlobalFunction<PyObject*(PyObject*, PyObject*)>("PyNumber_Divide");
+-    value_ = state->CreateCall(func,
+-                               arg0_->getValue(),
+-                               arg1_->getValue());
 +    if (inplace_) {
 +      if (impl_->inlined())
 +        impl_->emit_inplace_inline(fbuilder, this->type_);
 +      else
 +        impl_->emit(fbuilder, this->type_);
 +    }
-+    state->DecRef(arg0_->getValue());
-+    state->DecRef(arg1_->getValue());
-   }
- 
-   void
-@@ -404,6 +483,7 @@
-                                arg1_->getValue());
      state->DecRef(arg0_->getValue());
      state->DecRef(arg1_->getValue());
-+    this->getStaticType()->init(value_);
    }
- 
-   void
-@@ -417,6 +497,7 @@
-                                arg1_->getValue());
-     state->DecRef(arg0_->getValue());
-     state->DecRef(arg1_->getValue());
-+    this->getStaticType()->init(value_);
-   }
- 
-   void
-@@ -430,6 +511,7 @@
-                                arg1_->getValue());
-     state->DecRef(arg0_->getValue());
-     state->DecRef(arg1_->getValue());
-+    this->getStaticType()->init(value_);
-   }
- 
-   void
-@@ -443,6 +525,7 @@
-                                arg1_->getValue());
-     state->DecRef(arg0_->getValue());
-     state->DecRef(arg1_->getValue());
-+    this->getStaticType()->init(value_);
-   }
- 
-   void
-@@ -457,6 +540,38 @@
+@@ -457,6 +456,38 @@
  
      state->DecRef(arg0_->getValue());
      state->DecRef(arg1_->getValue());
    }
  
    void
-@@ -566,4 +681,24 @@
+@@ -566,4 +597,19 @@
      state->IncRef(arg_->getValue());
    }
  
 +  const int JITStoreFast::ID = 0;
 +  const int JITLoadFast::ID = 0;
 +  const int JITLoadConst::ID = 0;
-+  const int JITInplaceAdd::ID = 0;
-+  const int JITBinaryAdd::ID = 0;
-+  const int JITBinarySubtract::ID = 0;
-+  const int JITBinaryMultiply::ID = 0;
-+  const int JITBinaryDivide::ID = 0;
 +  const int JITCompareOp::ID = 0;
 +  const int JITIncRef::ID = 0;
 +  const int JITGuardNull::ID = 0;
      virtual void dump()
      {
        std::cout << "LOAD_CONST\n";
-@@ -124,16 +281,104 @@
+@@ -124,133 +281,112 @@
      {
        return value_;
      }
 +      return type_;
 +    }
 +
-+    virtual void registerStaticType(const PyTypeObject *)
-+    {
-+    }
-+
-+    virtual uintptr_t type()
-+    {
-+      return reinterpret_cast<uintptr_t>(&ID);
-+    }
-+    static const int ID;
-+
-   private:
-     int oparg_;
-     llvm::Value *value_;
-+    JITType *type_;
-+  };
-+
-+
-+  class JITGenericBinOp : public JITValue {
-+  public:
-+    JITGenericBinOp(BinaryOpImpl *impl, bool inplace, JITValue *arg0, JITValue *arg1);
-+
-+    ~JITGenericBinOp()
-+    {
-+      delete type_;
-+      delete impl_;
-+    }
-+
-+    virtual void dump()
-+    {
-+      std::cout << "GEN_BIN_OP\n";
-+    }
-+
-+    virtual void emit(JITFunctionBuilder &builder);
-+
-+    virtual llvm::Value *getValue() const
-+    {
-+      return getStaticType()->getValue();
-+    }
-+
-+    virtual JITType *getStaticType() const
-+    {
-+      return type_;
-+    }
-+
 +    virtual void registerStaticType(const PyTypeObject *t)
 +    {
 +      if (type_ == NULL || type_->canSpecialize(t)) {
 +    }
 +    static const int ID;
 +
-+  private:
-+    JITValue *arg0_;
-+    JITValue *arg1_;
+   private:
+     int oparg_;
+     llvm::Value *value_;
 +    JITType *type_;
-+    BinaryOpImpl *impl_;
-+    bool inplace_;
    };
  
-   class JITInplaceAdd : public JITValue {
+-  class JITInplaceAdd : public JITValue {
++
++  class JITGenericBinOp : public JITValue {
    public:
-     JITInplaceAdd(JITValue *arg0, JITValue *arg1)
+-    JITInplaceAdd(JITValue *arg0, JITValue *arg1)
 -      : arg0_(arg0), arg1_(arg1), value_(NULL)
 -    {}
-+      : arg0_(arg0), arg1_(arg1), value_(NULL), type_(new JITOpaqueObject),
-+        float_inline_(false)
-+    {
-+      if (arg0_->getStaticType()->isFloat() &&
-+          arg1_->getStaticType()->isFloat()) {
-+        this->registerStaticType(&PyFloat_Type);
-+        float_inline_ = true;
-+      }
-+    }
++    JITGenericBinOp(BinaryOpImpl *impl, bool inplace, JITValue *arg0, JITValue *arg1);
 +
-+    ~JITInplaceAdd()
++    ~JITGenericBinOp()
 +    {
 +      delete type_;
++      delete impl_;
 +    }
  
      virtual void dump()
      {
-@@ -144,20 +389,56 @@
+-      std::cout << "INPLACE_ADD\n";
++      std::cout << "GEN_BIN_OP\n";
+     }
+ 
+     virtual void emit(JITFunctionBuilder &builder);
  
      virtual llvm::Value *getValue() const
      {
    private:
      JITValue *arg0_;
      JITValue *arg1_;
-     llvm::Value *value_;
+-    llvm::Value *value_;
+-  };
+-
+-  class JITBinaryAdd : public JITValue {
+-  public:
+-    JITBinaryAdd(JITValue *arg0, JITValue *arg1)
+-      : arg0_(arg0), arg1_(arg1), value_(NULL)
+-    {}
+-
+-    virtual void dump()
+-    {
+-      std::cout << "BINARY_ADD\n";
+-    }
+-
+-    virtual void emit(JITFunctionBuilder &builder);
+-
+-    virtual llvm::Value *getValue() const
+-    {
+-      return value_;
+-    }
+-  private:
+-    JITValue *arg0_;
+-    JITValue *arg1_;
+-    llvm::Value *value_;
+-  };
+-
+-  class JITBinarySubtract : public JITValue {
+-  public:
+-    JITBinarySubtract(JITValue *arg0, JITValue *arg1)
+-      : arg0_(arg0), arg1_(arg1), value_(NULL)
+-    {}
+-
+-    virtual void dump()
+-    {
+-      std::cout << "BINARY_SUBSTRACT\n";
+-    }
+-
+-    virtual void emit(JITFunctionBuilder &builder);
+-
+-    virtual llvm::Value *getValue() const
+-    {
+-      return value_;
+-    }
+-  private:
+-    JITValue *arg0_;
+-    JITValue *arg1_;
+-    llvm::Value *value_;
+-  };
+-
+-  class JITBinaryMultiply : public JITValue {
+-  public:
+-    JITBinaryMultiply(JITValue *arg0, JITValue *arg1)
+-      : arg0_(arg0), arg1_(arg1), value_(NULL)
+-    {}
+-
+-    virtual void dump()
+-    {
+-      std::cout << "BINARY_MULTIPLY\n";
+-    }
+-
+-    virtual void emit(JITFunctionBuilder &builder);
+-
+-    virtual llvm::Value *getValue() const
+-    {
+-      return value_;
+-    }
+-  private:
+-    JITValue *arg0_;
+-    JITValue *arg1_;
+-    llvm::Value *value_;
+-  };
+-
+-  class JITBinaryDivide : public JITValue {
+-  public:
+-    JITBinaryDivide(JITValue *arg0, JITValue *arg1)
+-      : arg0_(arg0), arg1_(arg1), value_(NULL)
+-    {}
+-
+-    virtual void dump()
+-    {
+-      std::cout << "BINARY_DIVIDE\n";
+-    }
+-
+-    virtual void emit(JITFunctionBuilder &builder);
+-
+-    virtual llvm::Value *getValue() const
+-    {
+-      return value_;
+-    }
+-  private:
+-    JITValue *arg0_;
+-    JITValue *arg1_;
+-    llvm::Value *value_;
 +    JITType *type_;
-+    bool float_inline_;
-   };
- 
-   class JITBinaryAdd : public JITValue {
-   public:
-     JITBinaryAdd(JITValue *arg0, JITValue *arg1)
--      : arg0_(arg0), arg1_(arg1), value_(NULL)
-+      : arg0_(arg0), arg1_(arg1), value_(NULL), type_(new JITOpaqueObject)
-     {}
- 
-+    ~JITBinaryAdd()
-+    {
-+      delete type_;
-+    }
-+
-     virtual void dump()
-     {
-       std::cout << "BINARY_ADD\n";
-@@ -169,18 +450,40 @@
-     {
-       return value_;
-     }
-+
-+    virtual JITType *getStaticType() const
-+    {
-+      return type_;
-+    }
-+
-+    virtual void registerStaticType(const PyTypeObject *)
-+    {
-+    }
-+
-+    virtual uintptr_t type()
-+    {
-+      return reinterpret_cast<uintptr_t>(&ID);
-+    }
-+    static const int ID;
-+
-   private:
-     JITValue *arg0_;
-     JITValue *arg1_;
-     llvm::Value *value_;
-+    JITType *type_;
-   };
- 
-   class JITBinarySubtract : public JITValue {
-   public:
-     JITBinarySubtract(JITValue *arg0, JITValue *arg1)
--      : arg0_(arg0), arg1_(arg1), value_(NULL)
-+      : arg0_(arg0), arg1_(arg1), value_(NULL), type_(new JITOpaqueObject)
-     {}
- 
-+    ~JITBinarySubtract()
-+    {
-+      delete type_;
-+    }
-+
-     virtual void dump()
-     {
-       std::cout << "BINARY_SUBSTRACT\n";
-@@ -192,18 +495,40 @@
-     {
-       return value_;
-     }
-+
-+    virtual JITType *getStaticType() const
-+    {
-+      return type_;
-+    }
-+
-+    virtual void registerStaticType(const PyTypeObject *)
-+    {
-+    }
-+
-+    virtual uintptr_t type()
-+    {
-+      return reinterpret_cast<uintptr_t>(&ID);
-+    }
-+    static const int ID;
-+
-   private:
-     JITValue *arg0_;
-     JITValue *arg1_;
-     llvm::Value *value_;
-+    JITType *type_;
-   };
- 
-   class JITBinaryMultiply : public JITValue {
-   public:
-     JITBinaryMultiply(JITValue *arg0, JITValue *arg1)
--      : arg0_(arg0), arg1_(arg1), value_(NULL)
-+      : arg0_(arg0), arg1_(arg1), value_(NULL), type_(new JITOpaqueObject)
-     {}
- 
-+    ~JITBinaryMultiply()
-+    {
-+      delete type_;
-+    }
-+
-     virtual void dump()
-     {
-       std::cout << "BINARY_MULTIPLY\n";
-@@ -215,18 +540,40 @@
-     {
-       return value_;
-     }
-+
-+    virtual JITType *getStaticType() const
-+    {
-+      return type_;
-+    }
-+
-+    virtual void registerStaticType(const PyTypeObject *)
-+    {
-+    }
-+
-+    virtual uintptr_t type()
-+    {
-+      return reinterpret_cast<uintptr_t>(&ID);
-+    }
-+    static const int ID;
-+
-   private:
-     JITValue *arg0_;
-     JITValue *arg1_;
-     llvm::Value *value_;
-+    JITType *type_;
-   };
- 
-   class JITBinaryDivide : public JITValue {
-   public:
-     JITBinaryDivide(JITValue *arg0, JITValue *arg1)
--      : arg0_(arg0), arg1_(arg1), value_(NULL)
-+      : arg0_(arg0), arg1_(arg1), value_(NULL), type_(new JITOpaqueObject)
-     {}
- 
-+    ~JITBinaryDivide()
-+    {
-+      delete type_;
-+    }
-+
-     virtual void dump()
-     {
-       std::cout << "BINARY_DIVIDE\n";
-@@ -238,19 +585,41 @@
-     {
-       return value_;
-     }
-+
-+    virtual JITType *getStaticType() const
-+    {
-+      return type_;
-+    }
-+
-+    virtual void registerStaticType(const PyTypeObject *)
-+    {
-+    }
-+
-+    virtual uintptr_t type()
-+    {
-+      return reinterpret_cast<uintptr_t>(&ID);
-+    }
-+    static const int ID;
-+
-   private:
-     JITValue *arg0_;
-     JITValue *arg1_;
-     llvm::Value *value_;
-+    JITType *type_;
++    BinaryOpImpl *impl_;
++    bool inplace_;
    };
  
    class JITCompareOp : public JITValue {
      virtual void dump()
      {
        std::cout << "COMPARE_OP " << oparg_ << "\n";
-@@ -262,16 +631,33 @@
+@@ -262,16 +398,33 @@
      {
        return value_;
      }
      {}
  
      virtual void dump()
-@@ -281,21 +667,50 @@
+@@ -281,21 +434,50 @@
  
      virtual void emit(JITFunctionBuilder &builder);
  
      {}
  
      virtual void dump()
-@@ -305,24 +720,25 @@
+@@ -305,24 +487,25 @@
  
      virtual void emit(JITFunctionBuilder &builder);
  
      {}
  
      virtual void dump()
-@@ -332,22 +748,23 @@
+@@ -332,22 +515,23 @@
  
      virtual void emit(JITFunctionBuilder &builder);
  
      {}
  
      virtual void dump()
-@@ -357,24 +774,39 @@
+@@ -357,24 +541,39 @@
  
      virtual void emit(JITFunctionBuilder &builder);
  
      void dump()
      {
        for (size_t i = 0; i < loaded_stack_.size(); ++i) {
-@@ -387,6 +819,15 @@
+@@ -387,6 +586,15 @@
  
      void emit(JITFunctionState &state);
  
      JITForIter *createForIter(JITValue *v)
      {
        JITForIter *r = new JITForIter(v);
-@@ -394,6 +835,13 @@
+@@ -394,37 +602,9 @@
        return r;
      }
  
+-    JITInplaceAdd *createInplaceAdd(JITValue *v, JITValue *w)
 +    JITGenericBinOp *createGenericBinOp(BinaryOpImpl *impl, bool inplace, JITValue *v, JITValue *w)
-+    {
+     {
+-      JITInplaceAdd *r = new JITInplaceAdd(v, w);
+-      trace_.push_back(r);
+-      return r;
+-    }
+-
+-    JITBinaryAdd *createBinaryAdd(JITValue *v, JITValue *w)
+-    {
+-      JITBinaryAdd *r = new JITBinaryAdd(v, w);
+-      trace_.push_back(r);
+-      return r;
+-    }
+-
+-    JITBinarySubtract *createBinarySubtract(JITValue *v, JITValue *w)
+-    {
+-      JITBinarySubtract *r = new JITBinarySubtract(v, w);
+-      trace_.push_back(r);
+-      return r;
+-    }
+-
+-    JITBinaryMultiply *createBinaryMultiply(JITValue *v, JITValue *w)
+-    {
+-      JITBinaryMultiply *r = new JITBinaryMultiply(v, w);
+-      trace_.push_back(r);
+-      return r;
+-    }
+-
+-    JITBinaryDivide *createBinaryDivide(JITValue *v, JITValue *w)
+-    {
+-      JITBinaryDivide *r = new JITBinaryDivide(v, w);
 +      JITGenericBinOp *r = new JITGenericBinOp(impl, inplace, v, w);
-+      trace_.push_back(r);
-+      return r;
-+    }
-+
-     JITInplaceAdd *createInplaceAdd(JITValue *v, JITValue *w)
-     {
-       JITInplaceAdd *r = new JITInplaceAdd(v, w);
-@@ -436,16 +884,23 @@
+       trace_.push_back(r);
+       return r;
+     }
+@@ -436,16 +616,23 @@
        return r;
      }
  
        trace_.push_back(r);
        return r;
      }
-@@ -478,19 +933,18 @@
+@@ -478,19 +665,18 @@
        return r;
      }
  
 new file mode 100644
 --- /dev/null
 +++ b/JIT/jit_types.cc
-@@ -0,0 +1,35 @@
+@@ -0,0 +1,34 @@
 +#include "JIT/jit_types.h"
 +
 +namespace jit {
 +    return NULL;
 +  }
 +
-+
 +  JITType *
 +  JITType::createNakedType(const PyTypeObject *t)
 +  {
  
  ######################################################################
  
+diff --git a/Modules/_jit.c b/Modules/_jit.c
+--- a/Modules/_jit.c
++++ b/Modules/_jit.c
+@@ -3,6 +3,8 @@
+ static PyObject *
+ jit_activate_tracer(PyObject *self)
+ {
++  assert(PyThreadState_GET()->interp != NULL);
++  assert(PyThreadState_GET()->interp->global_jit_data != NULL);
+   PyJITTracer_On();
+   Py_RETURN_NONE;
+ }
+@@ -10,6 +12,8 @@
+ static PyObject *
+ jit_deactivate_tracer(PyObject *self)
+ {
++  assert(PyThreadState_GET()->interp != NULL);
++  assert(PyThreadState_GET()->interp->global_jit_data != NULL);
+   PyJITTracer_Off();
+   Py_RETURN_NONE;
+ }
+@@ -17,7 +21,7 @@
+ static struct PyMethodDef jit_methods[] = {
+   {"activate", (PyCFunction)jit_activate_tracer, METH_NOARGS},
+   {"deactivate", (PyCFunction)jit_deactivate_tracer, METH_NOARGS},
+-  { NULL, NULL }
++  { NULL, NULL, 0, NULL }
+ };
+ 
+ static struct PyModuleDef jitmodule = {
+@@ -31,12 +35,6 @@
+ PyMODINIT_FUNC
+ PyInit__jit(void)
+ {
+-  PyObject *module;
+-
+-  module = PyModule_Create(&jitmodule);
+-  if (module == NULL) {
+-    return NULL;
+-  }
+-  return module;
++  return PyModule_Create(&jitmodule);
+ }
+ 
 diff --git a/Objects/codeobject.c b/Objects/codeobject.c
 --- a/Objects/codeobject.c
 +++ b/Objects/codeobject.c
              break;
  
          TARGET(BINARY_LSHIFT)
-@@ -1677,6 +1728,8 @@
+@@ -1627,6 +1678,8 @@
+         TARGET(INPLACE_POWER)
+             w = POP();
+             v = TOP();
++            trace->setType(0, v->ob_type);
++            trace->setType(1, w->ob_type);
+             x = PyNumber_InPlacePower(v, w, Py_None);
+             Py_DECREF(v);
+             Py_DECREF(w);
+@@ -1637,6 +1690,8 @@
+         TARGET(INPLACE_MULTIPLY)
+             w = POP();
+             v = TOP();
++            trace->setType(0, v->ob_type);
++            trace->setType(1, w->ob_type);
+             x = PyNumber_InPlaceMultiply(v, w);
+             Py_DECREF(v);
+             Py_DECREF(w);
+@@ -1647,6 +1702,8 @@
+         TARGET(INPLACE_TRUE_DIVIDE)
+             w = POP();
+             v = TOP();
++            trace->setType(0, v->ob_type);
++            trace->setType(1, w->ob_type);
+             x = PyNumber_InPlaceTrueDivide(v, w);
+             Py_DECREF(v);
+             Py_DECREF(w);
+@@ -1657,6 +1714,8 @@
+         TARGET(INPLACE_FLOOR_DIVIDE)
+             w = POP();
+             v = TOP();
++            trace->setType(0, v->ob_type);
++            trace->setType(1, w->ob_type);
+             x = PyNumber_InPlaceFloorDivide(v, w);
+             Py_DECREF(v);
+             Py_DECREF(w);
+@@ -1667,6 +1726,8 @@
+         TARGET(INPLACE_MODULO)
+             w = POP();
+             v = TOP();
++            trace->setType(0, v->ob_type);
++            trace->setType(1, w->ob_type);
+             x = PyNumber_InPlaceRemainder(v, w);
+             Py_DECREF(v);
+             Py_DECREF(w);
+@@ -1677,6 +1738,8 @@
          TARGET(INPLACE_ADD)
              w = POP();
              v = TOP();
              if (PyUnicode_CheckExact(v) &&
                       PyUnicode_CheckExact(w)) {
                  x = unicode_concatenate(v, w, f, next_instr);
-@@ -2382,16 +2435,22 @@
+@@ -1696,6 +1759,8 @@
+         TARGET(INPLACE_SUBTRACT)
+             w = POP();
+             v = TOP();
++            trace->setType(0, v->ob_type);
++            trace->setType(1, w->ob_type);
+             x = PyNumber_InPlaceSubtract(v, w);
+             Py_DECREF(v);
+             Py_DECREF(w);
+@@ -2382,16 +2447,22 @@
              if (w == Py_False) {
                  Py_DECREF(w);
                  JUMPTO(oparg);
              DISPATCH();
  
          PREDICTED_WITH_ARG(POP_JUMP_IF_TRUE);
-@@ -2468,6 +2527,8 @@
+@@ -2468,6 +2539,8 @@
          PREDICTED_WITH_ARG(JUMP_ABSOLUTE);
          TARGET(JUMP_ABSOLUTE)
              JUMPTO(oparg);
  #if FAST_LOOPS
              /* Enabling this path speeds-up all while and for-loops by bypassing
                 the per-loop checks for signals.  By default, this should be turned-off
-@@ -2507,11 +2568,14 @@
+@@ -2507,11 +2580,14 @@
              }
              if (PyErr_Occurred()) {
                  if (!PyErr_ExceptionMatches(
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.