[pypy-commit] pypy dynamic-specialized-tuple: random hacking at this. I think we need a comprehensive solution to addresses in the JIT.

alex_gaynor noreply at buildbot.pypy.org
Wed Mar 14 22:02:17 CET 2012


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: dynamic-specialized-tuple
Changeset: r53602:bd7e5423874a
Date: 2012-03-14 14:01 -0700
http://bitbucket.org/pypy/pypy/changeset/bd7e5423874a/

Log:	random hacking at this. I think we need a comprehensive solution to
	addresses in the JIT.

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
@@ -1205,10 +1205,14 @@
         return lltype.cast_primitive(TYPE, x)
 
 def cast_to_ptr(x):
+    if lltype.typeOf(x) is llmemory.Address:
+        return llmemory.cast_adr_to_ptr(x, llmemory.GCREF)
     assert isinstance(lltype.typeOf(x), lltype.Ptr)
     return lltype.cast_opaque_ptr(llmemory.GCREF, x)
 
 def cast_from_ptr(TYPE, x):
+    if TYPE is llmemory.Address:
+        return llmemory.cast_ptr_to_adr(x)
     return lltype.cast_opaque_ptr(TYPE, x)
 
 def cast_to_floatstorage(x):
@@ -1458,21 +1462,21 @@
 def do_getfield_gc_ptr(struct, fieldnum):
     return cast_to_ptr(_getfield_gc(struct, fieldnum))
 
-def _getinteriorfield_gc(struct, fieldnum):
-    STRUCT, fieldname = symbolic.TokenToField[fieldnum]
-    return getattr(struct, fieldname)
+def new_getinteriorfield_gc(cast_func):
+    def do_getinteriorfield_gc(array, index, fieldnum):
+        STRUCT, fieldname = symbolic.TokenToField[fieldnum]
+        if isinstance(lltype.typeOf(array._obj.container), lltype.GcStruct):
+            array = getattr(array._obj.container, fieldname)
+            value = array.getitem(index)
+        else:
+            struct = array._obj.container.getitem(index)
+            value = getattr(struct, fieldname)
+        return cast_func(value)
+    return do_getinteriorfield_gc
 
-def do_getinteriorfield_gc_int(array, index, fieldnum):
-    struct = array._obj.container.getitem(index)
-    return cast_to_int(_getinteriorfield_gc(struct, fieldnum))
-
-def do_getinteriorfield_gc_float(array, index, fieldnum):
-    struct = array._obj.container.getitem(index)
-    return cast_to_floatstorage(_getinteriorfield_gc(struct, fieldnum))
-
-def do_getinteriorfield_gc_ptr(array, index, fieldnum):
-    struct = array._obj.container.getitem(index)
-    return cast_to_ptr(_getinteriorfield_gc(struct, fieldnum))
+do_getinteriorfield_gc_int = new_getinteriorfield_gc(cast_to_int)
+do_getinteriorfield_gc_float = new_getinteriorfield_gc(cast_to_floatstorage)
+do_getinteriorfield_gc_ptr = new_getinteriorfield_gc(cast_to_ptr)
 
 def _getinteriorfield_raw(ffitype, array, index, width, ofs):
     addr = rffi.cast(rffi.VOIDP, array)
@@ -1556,9 +1560,14 @@
 def new_setinteriorfield_gc(cast_func):
     def do_setinteriorfield_gc(array, index, fieldnum, newvalue):
         STRUCT, fieldname = symbolic.TokenToField[fieldnum]
-        struct = array._obj.container.getitem(index)
-        FIELDTYPE = getattr(STRUCT, fieldname)
-        setattr(struct, fieldname, cast_func(FIELDTYPE, newvalue))
+        if isinstance(lltype.typeOf(array._obj.container), lltype.GcStruct):
+            array = getattr(array._obj.container, fieldname)
+            FIELDTYPE = lltype.typeOf(array).OF
+            array.setitem(index, cast_func(FIELDTYPE, newvalue))
+        else:
+            struct = array._obj.container.getitem(index)
+            FIELDTYPE = getattr(STRUCT, fieldname)
+            setattr(struct, fieldname, cast_func(FIELDTYPE, newvalue))
     return do_setinteriorfield_gc
 do_setinteriorfield_gc_int = new_setinteriorfield_gc(cast_from_int)
 do_setinteriorfield_gc_float = new_setinteriorfield_gc(cast_from_floatstorage)
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -34,6 +34,7 @@
 
 class Transformer(object):
     vable_array_vars = None
+    _newoperations = None
 
     def __init__(self, cpu=None, callcontrol=None, portal_jd=None):
         self.cpu = cpu
@@ -243,7 +244,8 @@
     def rewrite_op_cast_int_to_unichar(self, op): pass
     def rewrite_op_cast_int_to_uint(self, op): pass
     def rewrite_op_cast_uint_to_int(self, op): pass
-    def rewrite_op_cast_ptr_to_adr(self, op): pass
+    def rewrite_op_cast_ptr_to_adr(self, op):
+        return op
 
     def _rewrite_symmetric(self, op):
         """Rewrite 'c1+v2' into 'v2+c1' in an attempt to avoid generating
@@ -833,6 +835,15 @@
             return SpaceOperation(opname, [op.args[0], op.args[2], op.args[3]],
                                   op.result)
         else:
+            kind = None
+            orig_value = None
+            orig_result = None
+            if self._newoperations and self._newoperations[-1].opname == "cast_ptr_to_adr":
+                prev_op = self._newoperations.pop()
+                kind = "r"
+                [orig_value] = prev_op.args
+                orig_result = prev_op.result
+
             v_inst = op.args[0]
             v_value = op.args[3]
             if v_value.concretetype is lltype.Void:
@@ -841,6 +852,11 @@
                 v_inst, v_index, c_field, v_value = op.args
             else:
                 v_inst, c_field, v_index, v_value = op.args
+
+            assert orig_result is None or orig_result is v_value
+            if orig_value is not None:
+                v_value = orig_value
+
             descr = self.cpu.interiorfielddescrof(v_inst.concretetype.TO,
                                                   c_field.value)
             kind = getkind(v_value.concretetype)[0]
diff --git a/pypy/jit/codewriter/test/test_jtransform.py b/pypy/jit/codewriter/test/test_jtransform.py
--- a/pypy/jit/codewriter/test/test_jtransform.py
+++ b/pypy/jit/codewriter/test/test_jtransform.py
@@ -1275,3 +1275,25 @@
     assert op1.opname == "getinteriorfield_gc_r"
     assert op1.args == [v0, const(0), ('interiorfielddescr', S, 'data')]
     assert op1.result == v2
+
+def test_cast_ptr_to_adr():
+    S = lltype.GcStruct("S",
+        ("data", lltype.Array(llmemory.Address)),
+    )
+
+    v0 = varoftype(lltype.Ptr(S))
+    v1 = varoftype(lltype.Ptr(S))
+    v2 = varoftype(llmemory.Address)
+
+    block = Block([v0, v1])
+    block.operations = [
+        SpaceOperation("cast_ptr_to_adr", [v1], v2),
+        SpaceOperation("setinteriorfield",
+            [v0, Constant("data", lltype.Void), const(0), v2], lltype.Void
+        )
+    ]
+
+    Transformer(FakeCPU()).optimize_block(block)
+    [op1] = block.operations
+    assert op1.opname == "setinteriorfield_gc_r"
+    assert op1.args == [v0, const(0), v1, ('interiorfielddescr', S, 'data')]


More information about the pypy-commit mailing list