Author: Alex Gaynor <alex.gay...@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')] _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit