[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