[pypy-commit] pypy dynamic-specialized-tuple: (arigo, alex): remove the old hacks, and start making this case use arrayfield

alex_gaynor noreply at buildbot.pypy.org
Wed Mar 14 23:20:00 CET 2012


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

Log:	(arigo, alex): remove the old hacks, and start making this case use
	arrayfield

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,14 +1205,10 @@
         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):
@@ -1464,14 +1460,8 @@
 
 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)
+        struct = array._obj.container.getitem(index)
+        return cast_func(getattr(struct, fieldname))
     return do_getinteriorfield_gc
 
 do_getinteriorfield_gc_int = new_getinteriorfield_gc(cast_to_int)
@@ -1560,14 +1550,9 @@
 def new_setinteriorfield_gc(cast_func):
     def do_setinteriorfield_gc(array, index, fieldnum, newvalue):
         STRUCT, fieldname = symbolic.TokenToField[fieldnum]
-        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))
+        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/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -334,17 +334,11 @@
         token = history.getkind(getattr(S, fieldname))
         return self.getdescr(ofs, token[0], name=fieldname)
 
-    def interiorfielddescrof(self, A, fieldname, force_kind=None):
+    def interiorfielddescrof(self, A, fieldname):
+        S = A.OF
         width = symbolic.get_size(A)
-        if isinstance(A, lltype.GcArray):
-            S = A.OF
-            ofs, size = symbolic.get_field_token(S, fieldname)
-            token = history.getkind(getattr(S, fieldname))
-        else:
-            ofs, size = symbolic.get_field_token(A, fieldname)
-            token = history.getkind(getattr(A, fieldname).OF)
-        if force_kind is not None:
-            token = force_kind
+        ofs, size = symbolic.get_field_token(S, fieldname)
+        token = history.getkind(getattr(S, fieldname))
         return self.getdescr(ofs, token[0], name=fieldname, width=width)
 
     def interiorfielddescrof_dynamic(self, offset, width, fieldsize,
@@ -394,25 +388,17 @@
         return llimpl.grab_exc_value()
 
     def arraydescrof(self, A):
+        assert A.OF != lltype.Void
+        assert isinstance(A, lltype.GcArray) or A._hints.get('nolength', False)
         size = symbolic.get_size(A)
-        if isinstance(A, lltype.GcStruct):
-            token = 'S'
+        if isinstance(A.OF, lltype.Ptr) or isinstance(A.OF, lltype.Primitive):
+            token = history.getkind(A.OF)[0]
+        elif isinstance(A.OF, lltype.Struct):
+            token = 's'
         else:
-            assert A.OF != lltype.Void
-            assert isinstance(A, lltype.GcArray) or A._hints.get('nolength', False)
-            if isinstance(A.OF, lltype.Ptr) or isinstance(A.OF, lltype.Primitive):
-                token = history.getkind(A.OF)[0]
-            elif isinstance(A.OF, lltype.Struct):
-                token = 's'
-            else:
-                token = '?'
+            token = '?'
         return self.getdescr(size, token)
 
-    def copy_and_change_descr_typeinfo_to_ptr(self, descr):
-        return self.getdescr(descr.ofs, "r", descr.extrainfo, descr.name,
-                             descr.arg_types, descr.count_fields_if_immut,
-                             descr.ffi_flags, descr.width)
-
     # ---------- the backend-dependent operations ----------
 
     def bh_strlen(self, string):
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
@@ -233,12 +233,13 @@
     def rewrite_op_cast_adr_to_ptr(self, op):
         # HACK
         prev_op = self._newoperations.pop()
-        if prev_op.opname != 'getinteriorfield_gc_i':
+        if prev_op.opname != 'getarrayitem_gc_i':
             raise Exception("Must cast_adr_to_ptr of directly read adr")
-        prev_op.opname = 'getinteriorfield_gc_r'
+        prev_op.opname = 'getarrayitem_gc_r'
         prev_op.result = op.result
-        descr = self.cpu.copy_and_change_descr_typeinfo_to_ptr(prev_op.args[2])
-        prev_op.args = prev_op.args[:2] + [descr]
+        prev_descr = prev_op.args[1]
+        descr = self.cpu.copy_and_change_descr_typeinfo_to_ptr(prev_descr)
+        prev_op.args = [prev_op.args[0]] + [descr] + prev_op.args[2:]
         return prev_op
 
     def rewrite_op_cast_bool_to_int(self, op): pass
@@ -812,21 +813,33 @@
             opname = "unicodegetitem"
             return SpaceOperation(opname, [op.args[0], op.args[2]], op.result)
         else:
+            v_inst = op.args[0]
+            parts_v = op.args[1:]
             if op.result.concretetype is lltype.Void:
                 return
-            v_inst = op.args[0]
+            kind = getkind(op.result.concretetype)[0]
+            if isinstance(v_inst.concretetype.TO, lltype.GcArray):
+                # only GcArray of Struct supported
+                STRUCT = v_inst.concretetype.TO.OF
+                assert isinstance(STRUCT, lltype.Struct)
 
-            if isinstance(v_inst.concretetype.TO, lltype.GcArray):
-                v_inst, v_index, c_field = op.args
+                v_index, c_field = parts_v
+                descr = self.cpu.interiorfielddescrof(v_inst.concretetype.TO,
+                                                      c_field.value)
+                args = [v_inst, v_index, descr]
+                return SpaceOperation('getinteriorfield_gc_%s' % kind, args,
+                                      op.result)
+            elif isinstance(v_inst.concretetype.TO, lltype.GcStruct):
+                # Supports the case of a GcStruct which contains an inlined
+                # array of simple types.
+                c_field, v_index = parts_v
+                assert v_inst.concretetype.TO._arrayfld == c_field.value
+                descr = self.cpu.arraydescrof(v_inst.concretetype.TO)
+                args = [v_inst, descr, v_index]
+                return SpaceOperation('getarrayitem_gc_%s' % kind, args,
+                                      op.result)
             else:
-                v_inst, c_field, v_index = op.args
-
-            descr = self.cpu.interiorfielddescrof(v_inst.concretetype.TO,
-                                                  c_field.value)
-            args = [v_inst, v_index, descr]
-            kind = getkind(op.result.concretetype)[0]
-            return SpaceOperation('getinteriorfield_gc_%s' % kind, args,
-                                  op.result)
+                raise Exception
 
     def rewrite_op_setinteriorfield(self, op):
         assert len(op.args) == 4
@@ -840,35 +853,44 @@
             return SpaceOperation(opname, [op.args[0], op.args[2], op.args[3]],
                                   op.result)
         else:
-            orig_value = None
-            orig_result = None
-            prev_op = None
-            if self._newoperations and self._newoperations[-1].opname == "cast_ptr_to_adr":
-                prev_op = self._newoperations.pop()
-                [orig_value] = prev_op.args
-                orig_result = prev_op.result
-
             v_inst = op.args[0]
-            v_value = op.args[3]
+            v_value = op.args[-1]
+            parts_v = op.args[1:-1]
             if v_value.concretetype is lltype.Void:
                 return
+
             if isinstance(v_inst.concretetype.TO, lltype.GcArray):
-                v_inst, v_index, c_field, v_value = op.args
+                # only GcArray of Struct supported
+                STRUCT = v_inst.concretetype.TO.OF
+                assert isinstance(STRUCT, lltype.Struct)
+
+                v_index, c_field = parts_v
+                descr = self.cpu.interiorfielddescrof(v_inst.concretetype.TO,
+                                                      c_field.value)
+                args = [v_inst, v_index, v_value, descr]
+                kind = getkind(v_value.concretetype)[0]
+                return SpaceOperation('setinteriorfield_gc_%s' % kind, args,
+                                      op.result)
+            elif isinstance(v_inst.concretetype.TO, lltype.GcStruct):
+                # Supports the case of a GcStruct which contains an inlined
+                # array of simple types.
+                c_field, v_index = parts_v
+                assert v_inst.concretetype.TO._arrayfld == c_field.value
+
+                descr = self.cpu.arraydescrof(v_inst.concretetype.TO)
+
+                if self._newoperations and self._newoperations[-1].opname == "cast_ptr_to_adr":
+                    prev_op = self._newoperations.pop()
+                    assert v_value is prev_op.result
+                    descr = self.cpu.copy_and_change_descr_typeinfo_to_ptr(descr)
+                    v_value = prev_op.args[0]
+
+                args = [v_inst, descr, v_index, v_value]
+                kind = getkind(v_value.concretetype)[0]
+                return SpaceOperation('setarrayitem_gc_%s' % kind, args,
+                                      op.result)
             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)
-            if prev_op is not None:
-                descr = self.cpu.copy_and_change_descr_typeinfo_to_ptr(descr)
-            kind = getkind(v_value.concretetype)[0]
-            args = [v_inst, v_index, v_value, descr]
-            return SpaceOperation('setinteriorfield_gc_%s' % kind, args,
-                                  op.result)
+                raise Exception("Obscure")
 
     def _rewrite_equality(self, op, opname):
         arg0, arg1 = op.args
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
@@ -1234,7 +1234,7 @@
     except Exception, e:
         assert 'foobar' in str(e)
 
-def test_interiorfield_struct():
+def test_arrayitem_struct():
     S = lltype.GcStruct("S",
         ("x", lltype.Signed),
         ("data", lltype.Array(lltype.Signed)),
@@ -1245,16 +1245,15 @@
         [v, c_data, const(0), const(1)], varoftype(lltype.Void)
     )
     op1 = Transformer(FakeCPU()).rewrite_operation(op)
-    assert op1.opname == "setinteriorfield_gc_i"
-    assert op1.args == [v, const(0), const(1), ('interiorfielddescr', S, "data")]
-
+    assert op1.opname == "setarrayitem_gc_i"
+    assert op1.args == [v, ('arraydescr', S), const(0), const(1)]
 
     op = SpaceOperation("getinteriorfield",
         [v, c_data, const(0)], varoftype(lltype.Signed)
     )
     op1 = Transformer(FakeCPU()).rewrite_operation(op)
-    assert op1.opname == "getinteriorfield_gc_i"
-    assert op1.args == [v, const(0), ('interiorfielddescr', S, "data")]
+    assert op1.opname == "getarrayitem_gc_i"
+    assert op1.args == [v, ('arraydescr', S), const(0)]
 
 def test_cast_adr_to_ptr():
     S = lltype.GcStruct("S",
@@ -1274,8 +1273,8 @@
 
     Transformer(FakeCPU()).optimize_block(block)
     [op1] = block.operations
-    assert op1.opname == "getinteriorfield_gc_r"
-    assert op1.args == [v0, const(0), (('interiorfielddescr', S, 'data'), "r")]
+    assert op1.opname == "getarrayitem_gc_r"
+    assert op1.args == [v0, (('arraydescr', S,), "r"), const(0)]
     assert op1.result == v2
 
 def test_cast_ptr_to_adr():
@@ -1297,5 +1296,5 @@
 
     Transformer(FakeCPU()).optimize_block(block)
     [op1] = block.operations
-    assert op1.opname == "setinteriorfield_gc_r"
-    assert op1.args == [v0, const(0), v1, (('interiorfielddescr', S, 'data'), "r")]
+    assert op1.opname == "setarrayitem_gc_r"
+    assert op1.args == [v0, (('arraydescr', S), "r"), const(0), v1]


More information about the pypy-commit mailing list