[pypy-svn] r62638 - in pypy/branch/pyjitpl5/pypy/jit: backend/llgraph backend/llgraph/test metainterp

arigo at codespeak.net arigo at codespeak.net
Fri Mar 6 13:33:35 CET 2009


Author: arigo
Date: Fri Mar  6 13:33:34 2009
New Revision: 62638

Added:
   pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py   (contents, props changed)
Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
   pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py
Log:
Add metainterp/executor.py, which collects all operations for a given
backend's CPU class.  Add a test for the llgraph backend.


Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py	Fri Mar  6 13:33:34 2009
@@ -451,3 +451,8 @@
         llimpl.frame_clear(self.frame, merge_point._compiled,
                            merge_point._opindex)
         self.merge_point = merge_point
+
+# ____________________________________________________________
+
+import pypy.jit.metainterp.executor
+pypy.jit.metainterp.executor.make_execute_list(CPU)

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py	Fri Mar  6 13:33:34 2009
@@ -5,6 +5,7 @@
 
 from pypy.jit.metainterp.history import BoxInt, BoxPtr, Const, ConstInt
 from pypy.jit.metainterp.resoperation import ResOperation, rop
+from pypy.jit.metainterp.executor import get_execute_function
 from pypy.jit.backend.llgraph.runner import CPU, GuardFailed
 
 
@@ -300,3 +301,11 @@
              ConstInt(calldescr),
              BoxInt(ord('A'))])
         assert x.value == ord('B')
+
+    def test_executor(self):
+        cpu = CPU(None)
+        fn = get_execute_function(cpu, rop.INT_ADD)
+        assert fn(cpu, [BoxInt(100), ConstInt(42)]).value == 142
+        fn = get_execute_function(cpu, rop.NEWSTR)
+        s = fn(cpu, [BoxInt(8)])
+        assert len(s.getptr(lltype.Ptr(rstr.STR)).chars) == 8

Added: pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/executor.py	Fri Mar  6 13:33:34 2009
@@ -0,0 +1,173 @@
+"""This implements pyjitpl's execution of operations.
+"""
+
+import py
+from pypy.rlib.rarithmetic import ovfcheck, r_uint
+from pypy.jit.metainterp.history import BoxInt, ConstInt, BoxPtr
+from pypy.jit.metainterp.resoperation import rop
+
+
+# Operations in the _ALWAYS_PURE part of the table of resoperation.py
+# must return a ConstInt or ConstPtr.  Other operations must return
+# a BoxInt or BoxPtr or None.
+
+# ____________________________________________________________
+
+def do_int_add(cpu, args):
+    return ConstInt(args[0].getint() + args[1].getint())
+
+def do_int_sub(cpu, args):
+    return ConstInt(args[0].getint() - args[1].getint())
+
+def do_int_mul(cpu, args):
+    return ConstInt(args[0].getint() * args[1].getint())
+
+def do_int_floordiv(cpu, args):
+    return ConstInt(args[0].getint() // args[1].getint())
+
+def do_int_mod(cpu, args):
+    return ConstInt(args[0].getint() % args[1].getint())
+
+def do_int_and(cpu, args):
+    return ConstInt(args[0].getint() & args[1].getint())
+
+def do_int_or(cpu, args):
+    return ConstInt(args[0].getint() | args[1].getint())
+
+def do_int_xor(cpu, args):
+    return ConstInt(args[0].getint() ^ args[1].getint())
+
+def do_int_rshift(cpu, args):
+    return ConstInt(args[0].getint() >> args[1].getint())
+
+def do_int_lshift(cpu, args):
+    return ConstInt(args[0].getint() << args[1].getint())
+
+do_uint_add = do_int_add
+do_uint_sub = do_int_sub
+do_uint_mul = do_int_mul
+
+# ----------
+
+def do_int_lt(cpu, args):
+    return ConstInt(args[0].getint() < args[1].getint())
+
+def do_int_le(cpu, args):
+    return ConstInt(args[0].getint() <= args[1].getint())
+
+def do_int_eq(cpu, args):
+    return ConstInt(args[0].getint() == args[1].getint())
+
+def do_int_ne(cpu, args):
+    return ConstInt(args[0].getint() != args[1].getint())
+
+def do_int_gt(cpu, args):
+    return ConstInt(args[0].getint() > args[1].getint())
+
+def do_int_ge(cpu, args):
+    return ConstInt(args[0].getint() >= args[1].getint())
+
+def do_uint_lt(cpu, args):
+    return ConstInt(r_uint(args[0].getint()) < r_uint(args[1].getint()))
+
+def do_uint_le(cpu, args):
+    return ConstInt(r_uint(args[0].getint()) <= r_uint(args[1].getint()))
+
+do_uint_eq = do_int_eq
+do_uint_ne = do_int_ne
+
+def do_uint_gt(cpu, args):
+    return ConstInt(r_uint(args[0].getint()) > r_uint(args[1].getint()))
+
+def do_uint_ge(cpu, args):
+    return ConstInt(r_uint(args[0].getint()) >= r_uint(args[1].getint()))
+
+# ----------
+
+def do_int_is_true(cpu, args):
+    return ConstInt(bool(args[0].getint()))
+
+def do_int_neg(cpu, args):
+    return ConstInt(-args[0].getint())
+
+def do_int_invert(cpu, args):
+    return ConstInt(~args[0].getint())
+
+def do_bool_not(cpu, args):
+    return ConstInt(not args[0].getint())
+
+def do_oononnull(cpu, args):
+    return ConstInt(bool(args[0].getptr_base()))
+
+def do_ooisnull(cpu, args):
+    return ConstInt(not args[0].getptr_base())
+
+def do_oois(cpu, args):
+    return ConstInt(args[0].getptr_base() == args[1].getptr_base())
+
+def do_ooisnot(cpu, args):
+    return ConstInt(args[0].getptr_base() != args[1].getptr_base())
+
+# ----------
+# the following operations just delegate to the cpu:
+
+#   do_arraylen_gc
+#   do_strlen
+#   do_strgetitem
+#   do_getarrayitem_gc
+#   do_getfield_gc
+#   do_getfield_raw
+#   do_new
+#   do_new_with_vtable
+#   do_new_array
+#   do_setarrayitem_gc
+#   do_setfield_gc
+#   do_setfield_raw
+#   do_newstr
+#   do_strsetitem
+#   do_call
+
+# ----------
+
+def do_int_add_ovf(cpu, args):
+    return BoxInt(ovfcheck(args[0].getint() + args[1].getint()))
+
+def do_int_sub_ovf(cpu, args):
+    return BoxInt(ovfcheck(args[0].getint() - args[1].getint()))
+
+def do_int_mul_ovf(cpu, args):
+    return BoxInt(ovfcheck(args[0].getint() * args[1].getint()))
+
+def do_int_neg_ovf(cpu, args):
+    return BoxInt(ovfcheck(-args[0].getint()))
+
+def do_int_mod_ovf(cpu, args):
+    return BoxInt(ovfcheck(args[0].getint() % args[1].getint()))
+
+# ____________________________________________________________
+
+
+def make_execute_list(cpuclass):
+    execute = [None] * (rop._LAST+1)
+    for key, value in rop.__dict__.items():
+        if not key.startswith('_'):
+            if (rop._SPECIAL_FIRST <= value <= rop._SPECIAL_LAST or
+                rop._GUARD_FIRST <= value <= rop._GUARD_LAST):
+                continue
+            if execute[value] is not None:
+                raise Exception("duplicate entry for op number %d" % value)
+            if key.endswith('_PURE'):
+                key = key[:-5]
+            name = 'do_' + key.lower()
+            try:
+                execute[value] = getattr(cpuclass, name)
+            except AttributeError:
+                execute[value] = globals()[name]
+    cpuclass._execute_list = execute
+
+def get_execute_function(cpu, opnum):
+    # workaround for an annotation limitation: putting this code in
+    # a specialize:memo function makes sure the following line is
+    # constant-folded away.  Only works if opnum is a constant, of course.
+    return cpu._execute_list[opnum]
+get_execute_function._annspecialcase_ = 'specialize:memo'

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/resoperation.py	Fri Mar  6 13:33:34 2009
@@ -68,10 +68,12 @@
 class rop(object):
     """The possible names of the ResOperations."""
 
+    _SPECIAL_FIRST = 1
     MERGE_POINT            = 1
     CATCH                  = 2
     JUMP                   = 3
     RETURN                 = 4
+    _SPECIAL_LAST = 9
 
     _GUARD_FIRST = 10 # ----- start of guard operations -----
     GUARD_TRUE             = 10



More information about the Pypy-commit mailing list