[pypy-commit] pypy jit-dynamic-getarrayitem: implement the optimization for set

alex_gaynor noreply at buildbot.pypy.org
Sun Nov 13 18:29:52 CET 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: jit-dynamic-getarrayitem
Changeset: r49377:af9eea9cddb5
Date: 2011-11-13 12:29 -0500
http://bitbucket.org/pypy/pypy/changeset/af9eea9cddb5/

Log:	implement the optimization for set

diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py
--- a/pypy/jit/backend/llgraph/llimpl.py
+++ b/pypy/jit/backend/llgraph/llimpl.py
@@ -20,6 +20,7 @@
 from pypy.jit.backend.llgraph import symbolic
 from pypy.jit.codewriter import longlong
 
+from pypy.rlib import libffi
 from pypy.rlib.objectmodel import ComputedIntSymbolic, we_are_translated
 from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint
@@ -848,6 +849,16 @@
         else:
             raise NotImplementedError
 
+    def op_setinteriorfield_raw(self, descr, array, index, newvalue):
+        if descr.typeinfo == REF:
+            return do_setinteriorfield_raw_ptr(array, index, newvalue, descr.extrainfo, descr.ofs)
+        elif descr.typeinfo == INT:
+            return do_setinteriorfield_raw_int(array, index, newvalue, descr.extrainfo, descr.ofs)
+        elif descr.typeinfo == FLOAT:
+            return do_setinteriorfield_raw_float(array, index, newvalue, descr.extrainfo, descr.ofs)
+        else:
+            raise NotImplementedError
+
     def op_setfield_gc(self, fielddescr, struct, newvalue):
         if fielddescr.typeinfo == REF:
             do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue)
@@ -1414,12 +1425,10 @@
     return cast_to_ptr(_getinteriorfield_gc(struct, fieldnum))
 
 def _getinteriorfield_raw(ffitype, array, index, width, ofs):
-    from pypy.rlib import libffi
     addr = rffi.cast(rffi.VOIDP, array)
     return libffi.array_getitem(ffitype, width, addr, index, ofs)
 
 def do_getinteriorfield_raw_int(array, index, width, ofs):
-    from pypy.rlib import libffi
     res = _getinteriorfield_raw(libffi.types.slong, array, index, width, ofs)
     return res
 
@@ -1501,6 +1510,13 @@
 do_setinteriorfield_gc_float = new_setinteriorfield_gc(cast_from_floatstorage)
 do_setinteriorfield_gc_ptr = new_setinteriorfield_gc(cast_from_ptr)
 
+def new_setinteriorfield_raw(ffitype):
+    def do_setinteriorfield_raw(array, index, newvalue, width, ofs):
+        addr = rffi.cast(rffi.VOIDP, array)
+        return libffi.array_setitem(ffitype, width, addr, index, ofs, newvalue)
+    return do_setinteriorfield_raw
+do_setinteriorfield_raw_int = new_setinteriorfield_raw(libffi.types.slong)
+
 def do_setfield_raw_int(struct, fieldnum, newvalue):
     STRUCT, fieldname = symbolic.TokenToField[fieldnum]
     ptr = cast_from_int(lltype.Ptr(STRUCT), struct)
diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py
--- a/pypy/jit/metainterp/executor.py
+++ b/pypy/jit/metainterp/executor.py
@@ -130,16 +130,6 @@
     else:
         return BoxInt(cpu.bh_getinteriorfield_gc_i(array, index, descr))
 
-def do_getinteriorfield_raw(cpu, _, arraybox, indexbox, descr):
-    array = arraybox.getref_base()
-    index = indexbox.getint()
-    if descr.is_pointer_field():
-        return BoxPtr(cpu.bh_getinteriorfield_raw_r(array, index, descr))
-    elif descr.is_float_field():
-        return BoxFloat(cpu.bh_getinteriorfield_raw_f(array, index, descr))
-    else:
-        return BoxInt(cpu.bh_getionteriorfield_raw_i(array, index, descr))
-
 def do_setinteriorfield_gc(cpu, _, arraybox, indexbox, valuebox, descr):
     array = arraybox.getref_base()
     index = indexbox.getint()
@@ -153,7 +143,6 @@
         cpu.bh_setinteriorfield_gc_i(array, index, descr,
                                      valuebox.getint())
 
-
 def do_getfield_gc(cpu, _, structbox, fielddescr):
     struct = structbox.getref_base()
     if fielddescr.is_pointer_field():
@@ -351,6 +340,8 @@
                          rop.DEBUG_MERGE_POINT,
                          rop.JIT_DEBUG,
                          rop.SETARRAYITEM_RAW,
+                         rop.GETINTERIORFIELD_RAW,
+                         rop.SETINTERIORFIELD_RAW,
                          rop.CALL_RELEASE_GIL,
                          rop.QUASIIMMUT_FIELD,
                          ):      # list of opcodes never executed by pyjitpl
diff --git a/pypy/jit/metainterp/optimizeopt/fficall.py b/pypy/jit/metainterp/optimizeopt/fficall.py
--- a/pypy/jit/metainterp/optimizeopt/fficall.py
+++ b/pypy/jit/metainterp/optimizeopt/fficall.py
@@ -118,8 +118,9 @@
             ops = self.do_push_arg(op)
         elif oopspec == EffectInfo.OS_LIBFFI_CALL:
             ops = self.do_call(op)
-        elif oopspec == EffectInfo.OS_LIBFFI_GETARRAYITEM:
-            ops = self.do_getarrayitem(op)
+        elif (oopspec == EffectInfo.OS_LIBFFI_GETARRAYITEM or
+            oopspec == EffectInfo.OS_LIBFFI_SETARRAYITEM):
+            ops = self.do_getsetarrayitem(op, oopspec)
         #
         for op in ops:
             self.emit_operation(op)
@@ -194,7 +195,7 @@
         ops.append(newop)
         return ops
 
-    def do_getarrayitem(self, op):
+    def do_getsetarrayitem(self, op, oopspec):
         ffitypeval = self.getvalue(op.getarg(1))
         widthval = self.getvalue(op.getarg(2))
         offsetval = self.getvalue(op.getarg(5))
@@ -211,10 +212,13 @@
             self.getvalue(op.getarg(3)).force_box(self.optimizer),
             self.getvalue(op.getarg(4)).force_box(self.optimizer),
         ]
+        if oopspec == EffectInfo.OS_LIBFFI_GETARRAYITEM:
+            opnum = rop.GETINTERIORFIELD_RAW
+        elif oopspec == EffectInfo.OS_LIBFFI_SETARRAYITEM:
+            opnum = rop.SETINTERIORFIELD_RAW
+            arglist.append(self.getvalue(op.getarg(6)).force_box(self.optimizer))
         return [
-            ResOperation(
-                rop.GETINTERIORFIELD_RAW, arglist, op.result, descr=descr
-            )
+            ResOperation(opnum, arglist, op.result, descr=descr),
         ]
 
     def _get_interior_descr(self, ffitype, width, offset):
diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -480,6 +480,7 @@
     'SETARRAYITEM_GC/3d',
     'SETARRAYITEM_RAW/3d',
     'SETINTERIORFIELD_GC/3d',
+    'SETINTERIORFIELD_RAW/3d',
     'SETFIELD_GC/2d',
     'SETFIELD_RAW/2d',
     'STRSETITEM/3',
diff --git a/pypy/jit/metainterp/test/test_fficall.py b/pypy/jit/metainterp/test/test_fficall.py
--- a/pypy/jit/metainterp/test/test_fficall.py
+++ b/pypy/jit/metainterp/test/test_fficall.py
@@ -149,6 +149,6 @@
                     return result_point[0].x * result_point[0].y
 
         assert self.meta_interp(main, [10]) == main(10) == 9000
-        self.check_loops({"int_add": 3, "jump": 1, "int_lt": 1,
+        self.check_loops({"int_add": 3, "jump": 1, "int_lt": 1, "guard_true": 1,
                           "getinteriorfield_raw": 4, "setinteriorfield_raw": 2
         })


More information about the pypy-commit mailing list