ebo avatar ebo committed fa1cc54

Added LOAD_GLOBAL opcode

Comments (0)

Files changed (1)

 new file mode 100644
 --- /dev/null
 +++ b/JIT/jit_blackhole.cc
-@@ -0,0 +1,69 @@
+@@ -0,0 +1,73 @@
 +#include "Python.h"
 +#include "frameobject.h"
 +#include "opcode.h"
 +      return BH_CONTINUE;
 +
 +    case BH_EXC_RAISED:
++      opcode = NEXTOP();
++      if (HAS_ARG(opcode))
++        oparg = NEXTARG();
++      frame->f_lasti = INSTR_OFFSET();
 +      return BH_EXC;
 +
 +    default:
 new file mode 100644
 --- /dev/null
 +++ b/JIT/jit_fbuilder.cc
-@@ -0,0 +1,179 @@
+@@ -0,0 +1,184 @@
 +#include "Python.h"
 +#include "opcode.h"
 +
 +    Function *func = this->state_->GetGlobalFunction<PyObject**(PyCodeObject*)>("_PyJIT_GetConstsFromCode");
 +    this->consts_ = this->state_->CreateCall(func, this->code_);
 +
++    globals_ = this->builder_.CreateLoad(FrameTy::f_globals(this->builder_, this->frame_), "globals");
++    builtins_ = this->builder_.CreateLoad(FrameTy::f_builtins(this->builder_, this->frame_), "globals");
++
++    names_ = this->builder_.CreateLoad(CodeTy::co_names(this->builder_, this->code_), "names");
++
 +    this->trace_block_ = this->state_->CreateBasicBlock("trace_block");
 +    this->builder_.CreateBr(this->trace_block_);
 +
 new file mode 100644
 --- /dev/null
 +++ b/JIT/jit_fbuilder.h
-@@ -0,0 +1,73 @@
+@@ -0,0 +1,89 @@
 +// -*- C++ -*-
 +#ifndef PYTHON_JIT_FBUILDER_H_
 +#define PYTHON_JIT_FBUILDER_H_
 +    llvm::Value *LocalPtr(int arg);
 +    llvm::Value *ConstPtr(int arg);
 +
++    llvm::Value *getNames()
++    {
++      return names_;
++    }
++    llvm::Value *getGlobals()
++    {
++      return globals_;
++    }
++    llvm::Value *getBuiltins()
++    {
++      return builtins_;
++    }
++
 +  private:
 +    void CreateBailBlock();
 +
 +    llvm::Value *fastlocals_;
 +    llvm::Value *code_;
 +    llvm::Value *consts_;
++    llvm::Value *globals_;
++    llvm::Value *builtins_;
++    llvm::Value *names_;
 +
 +    llvm::Value *lasti_store_;
 +    llvm::Value *bail_reason_;
 new file mode 100644
 --- /dev/null
 +++ b/JIT/jit_inline_functions.c
-@@ -0,0 +1,88 @@
+@@ -0,0 +1,146 @@
 +#include "Python.h"
 +#include "frameobject.h"
 +#include "longintrepr.h"
 +#include "opcode.h"
 +
++#ifndef Py_DEBUG
++#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))
++#else
++#define GETITEM(v, i) PyTuple_GetItem((v), (i))
++#endif
++
++static void
++format_exc_check_arg(PyObject *exc, const char *format_str, PyObject *obj)
++{
++    const char *obj_str;
++
++    if (!obj)
++        return;
++
++    obj_str = _PyUnicode_AsString(obj);
++    if (!obj_str)
++        return;
++
++    PyErr_Format(exc, format_str, obj_str);
++}
++
 +void output_info(PyObject *v)
 +{
 +  /* printf("OI: %lX\n", (unsigned long)(v->ob_type->tp_iternext)); */
 +  return floordiv;
 +}
 +
++#define GLOBAL_NAME_ERROR_MSG \
++    "global name '%.200s' is not defined"
++
++PyObject * __attribute__((always_inline))
++_PyJIT_LoadGlobal(PyObject *names, PyObject *globals, PyObject *builtins, int oparg)
++{
++  PyObject *w = GETITEM(names, oparg);
++  PyObject *x = NULL;
++  if (PyDict_CheckExact(globals)
++      && PyDict_CheckExact(builtins)) {
++    x = _PyDict_LoadGlobal((PyDictObject *)globals,
++                           (PyDictObject *)builtins,
++                           w);
++    if (x == NULL) {
++      if (!PyErr_Occurred())
++        format_exc_check_arg(PyExc_NameError,
++                             GLOBAL_NAME_ERROR_MSG, w);
++      return x;
++    }
++  }
++  else {
++    /* Slow-path if globals or builtins is not a dict */
++    x = PyObject_GetItem(globals, w);
++    if (x == NULL) {
++      x = PyObject_GetItem(builtins, w);
++      if (x == NULL) {
++        if (PyErr_ExceptionMatches(PyExc_KeyError))
++          format_exc_check_arg(
++                               PyExc_NameError,
++                               GLOBAL_NAME_ERROR_MSG, w);
++        return x;
++      }
++    }
++  }
++  return x;
++}
++
 +void __attribute__((always_inline))
 +_PyJIT_WrapIncref(PyObject *obj)
 +{
 new file mode 100644
 --- /dev/null
 +++ b/JIT/jit_tracer.cc
-@@ -0,0 +1,741 @@
+@@ -0,0 +1,767 @@
 +#include "Python.h"
 +#include "opcode.h"
 +
 +    case STORE_FAST:
 +    case LOAD_FAST:
 +    case LOAD_CONST:
++    case LOAD_GLOBAL:
 +    case JUMP_ABSOLUTE:
 +    case POP_TOP:
 +    case ROT_TWO:
 +        stack.Push(v);
 +        continue;
 +
++      case LOAD_GLOBAL:
++        v = this->createLoadGlobal(entry.oparg);
++        this->createGuardNull(v, BH_EXC_RAISED, entry.pc, stack, locals);
++        this->createIncRef(v);
++        stack.Push(v);
++        continue;
++
 +      case POP_TOP:
 +        v = stack.Pop();
 +        this->createDecRef(v);
 +        stack.Push(x);
 +        continue;
 +
++      case JUMP_ABSOLUTE:
++        continue;
++
 +      default:
 +        assert(false);
 +      }
 +    this->getStaticType()->init(value_);
 +  }
 +
++  void
++  JITLoadGlobal::emit(JITFunctionBuilder &fbuilder)
++  {
++    JITFunctionState *state = fbuilder.getState();
++    Value *func =
++      state->GetGlobalFunction<PyObject*(PyObject*, PyObject*, PyObject*, int)>("_PyJIT_LoadGlobal");
++    Value *v = state->CreateCall(func,
++                                 fbuilder.getNames(),
++                                 fbuilder.getGlobals(),
++                                 fbuilder.getBuiltins(),
++                                 ConstantInt::getSigned(Type::getInt32Ty(state->context()), oparg_));
++    this->getStaticType()->init(v);
++  }
++
 +  JITGenericBinOp::JITGenericBinOp(BinaryOpImpl *impl, bool inplace, JITValue *arg0, JITValue *arg1)
 +    : arg0_(arg0), arg1_(arg1),
 +      type_(NULL), impl_(impl),
 +  const int JITLocalValue::ID = 0;
 +  const int JITForIter::ID = 0;
 +  const int JITLoadConst::ID = 0;
++  const int JITLoadGlobal::ID = 0;
 +  const int JITCompareOp::ID = 0;
 +  const int JITIncRef::ID = 0;
 +  const int JITXDecRef::ID = 0;
 new file mode 100644
 --- /dev/null
 +++ b/JIT/jit_tracer.h
-@@ -0,0 +1,759 @@
+@@ -0,0 +1,829 @@
 +// -*- C++ -*-
 +#ifndef PYTHON_JIT_TRACER_H_
 +#define PYTHON_JIT_TRACER_H_
 +
 +    virtual void dump()
 +    {
-+      std::cout << "OPCODE_INFO\n";
++      std::cout << "OPCODE_INFO " << lasti_ << "\n";
 +    }
 +
 +    virtual void emit(JITFunctionBuilder &fbuilder)
 +    JITType *type_;
 +  };
 +
++  class JITLoadGlobal : public JITValue {
++  public:
++    JITLoadGlobal(int oparg)
++      : oparg_(oparg), type_(new JITOpaqueObject)
++    {}
++
++    ~JITLoadGlobal()
++    {
++      delete type_;
++    }
++
++    virtual void dump()
++    {
++      std::cout << "LOAD_GLOBAL " << oparg_ << "\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 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;
++
++          type_->setGuard(true);
++        }
++      }
++      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:
++    int oparg_;
++    JITType *type_;
++  };
++
 +
 +  class JITGenericBinOp : public JITValue {
 +  public:
 +      return r;
 +    }
 +
++    JITLoadGlobal *createLoadGlobal(int oparg)
++    {
++      JITLoadGlobal *r = new JITLoadGlobal(oparg);
++      trace_.push_back(r);
++      return r;
++    }
++
 +    JITIncRef *createIncRef(JITValue *v)
 +    {
 +      JITIncRef *r = new JITIncRef(v);
              x = PyNumber_InPlaceSubtract(v, w);
              Py_DECREF(v);
              Py_DECREF(w);
-@@ -2382,16 +2459,22 @@
+@@ -2123,6 +2200,8 @@
+             w = GETITEM(names, oparg);
+             if (PyDict_CheckExact(f->f_globals)
+                 && PyDict_CheckExact(f->f_builtins)) {
++                trace->setType(0, f->f_globals->ob_type);
++                trace->setType(1, f->f_builtins->ob_type);
+                 x = _PyDict_LoadGlobal((PyDictObject *)f->f_globals,
+                                        (PyDictObject *)f->f_builtins,
+                                        w);
+@@ -2130,6 +2209,7 @@
+                     if (!PyErr_Occurred())
+                         format_exc_check_arg(PyExc_NameError,
+                                              GLOBAL_NAME_ERROR_MSG, w);
++                    trace->setFlag(TR_EXCEPTION);
+                     break;
+                 }
+                 Py_INCREF(x);
+@@ -2144,6 +2224,7 @@
+                             format_exc_check_arg(
+                                         PyExc_NameError,
+                                         GLOBAL_NAME_ERROR_MSG, w);
++                        trace->setFlag(TR_EXCEPTION);
+                         break;
+                     }
+                 }
+@@ -2382,16 +2463,22 @@
              if (w == Py_False) {
                  Py_DECREF(w);
                  JUMPTO(oparg);
              DISPATCH();
  
          PREDICTED_WITH_ARG(POP_JUMP_IF_TRUE);
-@@ -2468,6 +2551,9 @@
+@@ -2468,6 +2555,9 @@
          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 +2593,14 @@
+@@ -2507,11 +2597,14 @@
              }
              if (PyErr_Occurred()) {
                  if (!PyErr_ExceptionMatches(
              x = v = POP();
              Py_DECREF(v);
              JUMPBY(oparg);
-@@ -3077,6 +3166,7 @@
+@@ -3077,6 +3170,7 @@
  
      /* pop frame */
  exit_eval_frame:
 new file mode 100644
 --- /dev/null
 +++ b/dotests.py
-@@ -0,0 +1,188 @@
+@@ -0,0 +1,202 @@
 +import unittest
 +import _jit
 +
 +        self.analyse(doit, self.seq_float)
 +        self.analyse(doit, self.seq_int)
 +
++    def testGlobalsSimple(self):
++        global TEST_GLOBALS_SIMPLE
++        TEST_GLOBALS_SIMPLE = 2.0
++
++        def doit(seq):
++            acc = 0.0
++            for i in seq:
++                i += i
++                a = i + TEST_GLOBALS_SIMPLE
++                acc += a
++
++        self.analyse(doit, self.seq_float)
++        self.analyse(doit, self.seq_int)
++
 +
 +class TestCompares(Utilities, unittest.TestCase):
 +    def testComparesSimple(self):
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.