1. ebo
  2. Heaped Dove

Commits

ebo  committed f1f4d04

Added basic CALL_FUNCTION handling

  • Participants
  • Parent commits d862eb7
  • Branches default

Comments (0)

Files changed (1)

File jit.patch

View file
 new file mode 100644
 --- /dev/null
 +++ b/JIT/jit_tracer.cc
-@@ -0,0 +1,818 @@
+@@ -0,0 +1,904 @@
 +#include "Python.h"
 +#include "opcode.h"
 +
 +    case DUP_TOP:
 +    case DUP_TOP_TWO:
 +    case STORE_SUBSCR:
++    case CALL_FUNCTION:
 +
 +    case INPLACE_ADD:
 +    case INPLACE_SUBTRACT:
 +  }
 +#endif
 +
++  // state.function()->dump();
 +  PyGlobalJITData::Get()->optimize(state.function());
-+  // state.function()->dump();
++  state.function()->dump();
 +
 +  if (code->co_jit == NULL) {
 +    int codesize = PyBytes_GET_SIZE(code->co_code);
 +  }
 +
 +  void
++  JITTraceAnalysis::createCallFunctionOp(JITStack &stack, JITLocals &locals, TraceEntry &entry)
++  {
++    int oparg = entry.oparg;
++    std::vector<JITValue *> args(oparg, NULL);
++    while (--oparg >= 0) {
++      args[oparg] = stack.Pop();
++    }
++    JITValue *func = stack.Pop();
++    JITValue *res = this->createCallFunction(func, args, stack, locals);
++    this->createGuardNull(res, BH_EXC_RAISED, entry.pc, stack, locals);
++    stack.Push(res);
++  }
++
++  void
 +  JITTraceAnalysis::analyseTrace(std::vector<TraceEntry> &trace)
 +  {
 +    JITStack stack;
 +        }
 +        continue;
 +
++      case CALL_FUNCTION:
++        this->createCallFunctionOp(stack, locals, entry);
++        continue;
++
 +      case FOR_ITER:
 +        v = stack.Top();
 +        x = this->createForIter(v);
 +    arg1_->DecRef(fbuilder);
 +  }
 +
++  JITCallFunction::JITCallFunction(JITValue *func,
++                                   std::vector<JITValue *> &args,
++                                   std::vector<JITValue *> &stack,
++                                   std::vector<JITValue *> &locals)
++    : func_(func),
++      args_(args), stack_(stack), locals_(locals),
++      type_(NULL)
++  {
++  }
++
++  void
++  JITCallFunction::emit(JITFunctionBuilder &fbuilder)
++  {
++    JITFunctionState::BuilderT &builder = fbuilder.builder();
++    JITFunctionState *state = fbuilder.getState();
++
++    size_t na = args_.size();
++    Value *t_new = state->GetGlobalFunction<PyObject *(int)>("PyTuple_New");
++    Value *args = state->CreateCall(t_new, ConstantInt::getSigned(Type::getInt32Ty(state->context()), na));
++
++    llvm::BasicBlock *trace_cont = state->CreateBasicBlock("trace_cont");
++    llvm::BasicBlock *bail_args = state->CreateBasicBlock("bail_args");
++
++    builder.CreateCondBr(state->IsNull(args), bail_args, trace_cont);
++
++    builder.SetInsertPoint(bail_args);
++    for (size_t i = 0; i < locals_.size(); ++i) {
++      if (locals_[i] != NULL)
++        fbuilder.StoreLocal(i, locals_[i]->getStaticType()->getValue(fbuilder, false, false));
++    }
++    for (size_t i = 0; i < stack_.size(); ++i) {
++      fbuilder.Push(stack_[i]->getStaticType()->getValue(fbuilder, false, false));
++    }
++    fbuilder.Push(func_->getStaticType()->getValue(fbuilder, false, false));
++    for (size_t i = 0; i < args_.size(); ++i) {
++      fbuilder.Push(args_[i]->getStaticType()->getValue(fbuilder, false, false));
++    }
++
++    fbuilder.SetBailReason(BH_EXC_RAISED);
++
++    fbuilder.CreateBailBr();
++
++    builder.SetInsertPoint(trace_cont);
++
++    Value *as_tuple = builder.CreateBitCast(args, PyTypeBuilder<PyTupleObject*>::get(state->context()));
++    Value *items = TupleTy::ob_item(builder, as_tuple);
++    items = builder.CreateBitCast(items, PyTypeBuilder<PyObject**>::get(state->context()));
++    for (size_t i = 0; i < args_.size(); ++i) {
++      Value *gep = builder.CreateGEP(items,
++                                     ConstantInt::getSigned(Type::getInt32Ty(state->context()), i));
++      gep->dump();
++      gep->getType()->dump();
++      builder.CreateStore(args_[i]->getValue(fbuilder),
++                          gep);
++    }
++
++    Value *call = state->GetGlobalFunction<PyObject *(PyObject *, PyObject *, PyObject *)>("PyObject_Call");
++
++    Value *res = state->CreateCall(call,
++                                   func_->getValue(fbuilder),
++                                   args,
++                                   state->GetNull<PyObject *>());
++    this->getStaticType()->init(res);
++  }
++
 +  void
 +  JITCompareOp::emit(JITFunctionBuilder &fbuilder)
 +  {
 +  const int JITGuardType::ID = 0;
 +  const int JITGuardTrue::ID = 0;
 +  const int JITTraceEnd::ID = 0;
++  const int JITCallFunction::ID = 0;
 +
 +  const int JITGenericBinOp::ID = 0;
 +
 new file mode 100644
 --- /dev/null
 +++ b/JIT/jit_tracer.h
-@@ -0,0 +1,871 @@
+@@ -0,0 +1,945 @@
 +// -*- C++ -*-
 +#ifndef PYTHON_JIT_TRACER_H_
 +#define PYTHON_JIT_TRACER_H_
 +    JITType *type_;
 +  };
 +
-+
-+  class JITGenericBinOp : public JITValue {
++  class JITCallFunction : public JITValue {
 +  public:
-+    JITGenericBinOp(BinaryOpImpl *impl, bool inplace, JITValue *arg0, JITValue *arg1);
-+
-+    ~JITGenericBinOp()
++    JITCallFunction(JITValue *func,
++                    std::vector<JITValue *> &args,
++                    std::vector<JITValue *> &stack,
++                    std::vector<JITValue *> &locals);
++
++    ~JITCallFunction()
 +    {
 +      delete type_;
-+      delete impl_;
 +    }
 +
 +    virtual void dump()
 +    {
-+      std::cout << "GEN_BIN_OP\n";
-+    }
-+
-+    virtual void emit(JITFunctionBuilder &builder);
++      std::cout << "CALL_FUNCTION " << args_.size() << "\n";
++    }
++
++    virtual void emit(JITFunctionBuilder &fbuilder);
 +
 +    virtual llvm::Value *getValue(JITFunctionBuilder &fbuilder) const
 +    {
 +    static const int ID;
 +
 +  private:
-+    JITValue *arg0_;
-+    JITValue *arg1_;
++    JITValue *func_;
++    std::vector<JITValue *> args_;
++    std::vector<JITValue *> stack_;
++    std::vector<JITValue *> locals_;
 +    JITType *type_;
-+    BinaryOpImpl *impl_;
-+    bool inplace_;
 +  };
 +
-+  class JITCompareOp : public JITValue {
++  class JITGenericBinOp : public JITValue {
 +  public:
-+    JITCompareOp(JITValue *arg0, JITValue *arg1, int oparg)
-+      : arg0_(arg0), arg1_(arg1),
-+        oparg_(oparg), value_(NULL), type_(new JITOpaqueObject)
-+    {
-+    }
-+
-+    ~JITCompareOp()
++    JITGenericBinOp(BinaryOpImpl *impl, bool inplace, JITValue *arg0, JITValue *arg1);
++
++    ~JITGenericBinOp()
 +    {
 +      delete type_;
++      delete impl_;
 +    }
 +
 +    virtual void dump()
 +    {
-+      std::cout << "COMPARE_OP " << oparg_ << "\n";
++      std::cout << "GEN_BIN_OP\n";
 +    }
 +
 +    virtual void emit(JITFunctionBuilder &builder);
 +
++    virtual llvm::Value *getValue(JITFunctionBuilder &fbuilder) const
++    {
++      return getStaticType()->getValue(fbuilder);
++    }
++
++    virtual llvm::Value *getNakedValue(JITFunctionBuilder &fbuilder) const
++    {
++      return getStaticType()->getNakedValue(fbuilder);
++    }
++
 +    virtual JITType *getStaticType() const
 +    {
 +      return type_;
 +    }
 +
-+    virtual llvm::Value *getValue(JITFunctionBuilder &fbuilder) const
-+    {
-+      return getStaticType()->getValue(fbuilder);
-+    }
-+
-+    virtual llvm::Value *getNakedValue(JITFunctionBuilder &fbuilder) const
-+    {
-+      return getStaticType()->getNakedValue(fbuilder);
-+    }
-+
 +    virtual void registerStaticType(const PyTypeObject *t)
 +    {
 +      if (type_ == NULL || type_->canSpecialize(t)) {
 +  private:
 +    JITValue *arg0_;
 +    JITValue *arg1_;
++    JITType *type_;
++    BinaryOpImpl *impl_;
++    bool inplace_;
++  };
++
++  class JITCompareOp : public JITValue {
++  public:
++    JITCompareOp(JITValue *arg0, JITValue *arg1, int oparg)
++      : arg0_(arg0), arg1_(arg1),
++        oparg_(oparg), value_(NULL), type_(new JITOpaqueObject)
++    {
++    }
++
++    ~JITCompareOp()
++    {
++      delete type_;
++    }
++
++    virtual void dump()
++    {
++      std::cout << "COMPARE_OP " << oparg_ << "\n";
++    }
++
++    virtual void emit(JITFunctionBuilder &builder);
++
++    virtual JITType *getStaticType() const
++    {
++      return type_;
++    }
++
++    virtual llvm::Value *getValue(JITFunctionBuilder &fbuilder) const
++    {
++      return getStaticType()->getValue(fbuilder);
++    }
++
++    virtual llvm::Value *getNakedValue(JITFunctionBuilder &fbuilder) const
++    {
++      return getStaticType()->getNakedValue(fbuilder);
++    }
++
++    virtual void registerStaticType(const PyTypeObject *t)
++    {
++      if (type_ == NULL || type_->canSpecialize(t)) {
++        JITType *new_type = JITType::createBoxedType(t);
++        if (new_type != NULL) {
++          JITType *old_type = type_;
++          type_ = new_type;
++          delete old_type;
++        }
++      }
++      else {
++        if (!type_->matchesType(t)) {
++          std::cout << "Trace Type mismatch\n";
++        }
++      }
++    }
++
++    virtual uintptr_t type()
++    {
++      return reinterpret_cast<uintptr_t>(&ID);
++    }
++    static const int ID;
++
++  private:
++    JITValue *arg0_;
++    JITValue *arg1_;
 +    int oparg_;
 +    llvm::Value *value_;
 +    JITType *type_;
 +
 +    void createBinaryOp(bool inplace, JITStack &stack, JITLocals &locals, TraceEntry &entry);
 +
++    void createCallFunctionOp(JITStack &stack, JITLocals &locals, TraceEntry &entry);
++
++    JITCallFunction *createCallFunction(JITValue *func, std::vector<JITValue *> &args,
++                                        JITStack &stack, JITLocals &locals)
++    {
++      JITCallFunction *r = new JITCallFunction(func, args, stack.stack, locals.locals);
++      trace_.push_back(r);
++      return r;
++    }
++
 +    JITOpcodeInfo *createOpcodeInfo(int lasti, JITStack &stack, JITLocals &locals)
 +    {
 +      JITOpcodeInfo *r = new JITOpcodeInfo(lasti, stack.stack, locals.locals);
              x = v = POP();
              Py_DECREF(v);
              JUMPBY(oparg);
-@@ -3077,6 +3179,7 @@
+@@ -2682,6 +2784,7 @@
+             PUSH(x);
+             if (x != NULL)
+                 DISPATCH();
++            trace->setFlag(TR_EXCEPTION);
+             break;
+         }
+ 
+@@ -3077,6 +3180,7 @@
  
      /* pop frame */
  exit_eval_frame: