Author: Armin Rigo <ar...@tunes.org> Branch: ffi-backend Changeset: r55811:b8dc5e65e118 Date: 2012-06-24 21:30 +0200 http://bitbucket.org/pypy/pypy/changeset/b8dc5e65e118/
Log: (fijal, arigo) We added tests and removed code. Progress. We also broke stuff, but well, later. 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 @@ -21,7 +21,6 @@ from pypy.jit.backend.llgraph import symbolic from pypy.jit.codewriter import longlong -from pypy.rlib import libffi, clibffi 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 @@ -850,7 +849,7 @@ elif arraydescr.typeinfo == INT: return do_raw_load_int(addr, offset, arraydescr.ofs) elif arraydescr.typeinfo == FLOAT: - xxx + return do_raw_load_float(addr, offset, arraydescr.ofs) else: raise NotImplementedError @@ -939,9 +938,7 @@ raise NotImplementedError def op_setfield_raw(self, fielddescr, struct, newvalue): - if fielddescr.arg_types == 'dynamic': # abuse of .arg_types - do_setfield_raw_dynamic(struct, fielddescr, newvalue) - elif fielddescr.typeinfo == REF: + if fielddescr.typeinfo == REF: do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue) elif fielddescr.typeinfo == INT: do_setfield_raw_int(struct, fielddescr.ofs, newvalue) @@ -1496,18 +1493,6 @@ struct = array._obj.container.getitem(index) return cast_to_ptr(_getinteriorfield_gc(struct, fieldnum)) -def _getinteriorfield_raw(ffitype, array, index, width, ofs): - addr = rffi.cast(rffi.VOIDP, array) - return libffi.array_getitem(ffitype, width, addr, index, ofs) - -def do_getinteriorfield_raw_int(array, index, width, ofs): - res = _getinteriorfield_raw(libffi.types.slong, array, index, width, ofs) - return res - -def do_getinteriorfield_raw_float(array, index, width, ofs): - res = _getinteriorfield_raw(libffi.types.double, array, index, width, ofs) - return res - def _getfield_raw(struct, fieldnum): STRUCT, fieldname = symbolic.TokenToField[fieldnum] ptr = cast_from_int(lltype.Ptr(STRUCT), struct) @@ -1522,17 +1507,6 @@ def do_getfield_raw_ptr(struct, fieldnum): return cast_to_ptr(_getfield_raw(struct, fieldnum)) -def do_getfield_raw_dynamic(struct, fielddescr): - from pypy.rlib import libffi - addr = cast_from_int(rffi.VOIDP, struct) - ofs = fielddescr.ofs - if fielddescr.is_pointer_field(): - assert False, 'fixme' - elif fielddescr.is_float_field(): - assert False, 'fixme' - else: - return libffi._struct_getfield(lltype.Signed, addr, ofs) - def do_raw_load_int(struct, offset, descrofs): TYPE = symbolic.Size2Type[descrofs] ll_p = rffi.cast(rffi.CCHARP, struct) @@ -1540,6 +1514,13 @@ value = ll_p[0] return rffi.cast(lltype.Signed, value) +def do_raw_load_float(struct, offset, descrofs): + TYPE = symbolic.Size2Type[descrofs] + ll_p = rffi.cast(rffi.CCHARP, struct) + ll_p = rffi.cast(lltype.Ptr(TYPE), rffi.ptradd(ll_p, offset)) + value = ll_p[0] + return rffi.cast(lltype.Float, value) + def do_raw_store_int(struct, offset, descrofs, value): TYPE = symbolic.Size2Type[descrofs] ll_p = rffi.cast(rffi.CCHARP, struct) @@ -1610,18 +1591,6 @@ do_setinteriorfield_gc_float = new_setinteriorfield_gc(cast_from_floatstorage) do_setinteriorfield_gc_ptr = new_setinteriorfield_gc(cast_from_ptr) -def new_setinteriorfield_raw(cast_func, ffitype): - def do_setinteriorfield_raw(array, index, newvalue, width, ofs): - addr = rffi.cast(rffi.VOIDP, array) - for TYPE, ffitype2 in clibffi.ffitype_map: - if ffitype2 is ffitype: - newvalue = cast_func(TYPE, newvalue) - break - return libffi.array_setitem(ffitype, width, addr, index, ofs, newvalue) - return do_setinteriorfield_raw -do_setinteriorfield_raw_int = new_setinteriorfield_raw(cast_from_int, libffi.types.slong) -do_setinteriorfield_raw_float = new_setinteriorfield_raw(cast_from_floatstorage, libffi.types.double) - def do_setfield_raw_int(struct, fieldnum, newvalue): STRUCT, fieldname = symbolic.TokenToField[fieldnum] ptr = cast_from_int(lltype.Ptr(STRUCT), struct) @@ -1643,17 +1612,6 @@ newvalue = cast_from_ptr(FIELDTYPE, newvalue) setattr(ptr, fieldname, newvalue) -def do_setfield_raw_dynamic(struct, fielddescr, newvalue): - from pypy.rlib import libffi - addr = cast_from_int(rffi.VOIDP, struct) - ofs = fielddescr.ofs - if fielddescr.is_pointer_field(): - assert False, 'fixme' - elif fielddescr.is_float_field(): - assert False, 'fixme' - else: - libffi._struct_setfield(lltype.Signed, addr, ofs, newvalue) - def do_newstr(length): x = rstr.mallocstr(length) return cast_to_ptr(x) diff --git a/pypy/jit/backend/llsupport/descr.py b/pypy/jit/backend/llsupport/descr.py --- a/pypy/jit/backend/llsupport/descr.py +++ b/pypy/jit/backend/llsupport/descr.py @@ -237,29 +237,6 @@ cache[(ARRAY, name)] = descr return descr -def compute_flag(is_pointer, is_float, is_signed): - if is_pointer: - assert not is_float - return FLAG_POINTER - elif is_float: - return FLAG_FLOAT - elif is_signed: - return FLAG_SIGNED - else: - return FLAG_UNSIGNED - -def get_dynamic_field_descr(offset, fieldsize, is_pointer, is_float, is_signed): - flag = compute_flag(is_pointer, is_float, is_signed) - return FieldDescr('dynamic', offset, fieldsize, flag) - -def get_dynamic_interiorfield_descr(gc_ll_descr, offset, width, fieldsize, - is_pointer, is_float, is_signed): - arraydescr = ArrayDescr(0, width, None, FLAG_STRUCT) - flag = compute_flag(is_pointer, is_float, is_signed) - fielddescr = FieldDescr('dynamic', offset, fieldsize, flag) - return InteriorFieldDescr(arraydescr, fielddescr) - - # ____________________________________________________________ # CallDescrs diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -3340,6 +3340,58 @@ fail = self.cpu.execute_token(looptoken2, -9) assert fail.identifier == 42 + def test_raw_load_int(self): + from pypy.rlib import rawstorage + for T in [rffi.UCHAR, rffi.SIGNEDCHAR, + rffi.USHORT, rffi.SHORT, + rffi.UINT, rffi.INT, + rffi.ULONG, rffi.LONG]: + ops = """ + [i0, i1] + i2 = raw_load(i0, i1, descr=arraydescr) + finish(i2) + """ + arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) + p = rawstorage.alloc_raw_storage(31) + for i in range(31): + p[i] = '\xDD' + value = rffi.cast(T, 0x4243444546474849) + rawstorage.raw_storage_setitem(p, 16, value) + loop = parse(ops, self.cpu, namespace=locals()) + looptoken = JitCellToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + self.cpu.execute_token(looptoken, + rffi.cast(lltype.Signed, p), 16) + result = self.cpu.get_latest_value_int(0) + assert result == rffi.cast(lltype.Signed, value) + rawstorage.free_raw_storage(p) + + def test_raw_load_float(self): + if not self.cpu.supports_floats: + py.test.skip("requires floats") + from pypy.rlib import rawstorage + for T in [rffi.DOUBLE]: + ops = """ + [i0, i1] + f2 = raw_load(i0, i1, descr=arraydescr) + finish(f2) + """ + arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) + p = rawstorage.alloc_raw_storage(31) + for i in range(31): + p[i] = '\xDD' + value = rffi.cast(T, 1.12e20) + rawstorage.raw_storage_setitem(p, 16, value) + loop = parse(ops, self.cpu, namespace=locals()) + looptoken = JitCellToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + self.cpu.execute_token(looptoken, + rffi.cast(lltype.Signed, p), 16) + result = self.cpu.get_latest_value_float(0) + result = longlong.getrealfloat(result) + assert result == rffi.cast(lltype.Float, value) + rawstorage.free_raw_storage(p) + class OOtypeBackendTest(BaseBackendTest): diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py --- a/pypy/jit/backend/x86/assembler.py +++ b/pypy/jit/backend/x86/assembler.py @@ -1570,9 +1570,6 @@ ofs_loc) self.load_from_mem(resloc, src_addr, fieldsize_loc, sign_loc) - genop_getinteriorfield_raw = genop_getinteriorfield_gc - - def genop_discard_setfield_gc(self, op, arglocs): base_loc, ofs_loc, size_loc, value_loc = arglocs assert isinstance(size_loc, ImmedLoc) diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py --- a/pypy/jit/backend/x86/regalloc.py +++ b/pypy/jit/backend/x86/regalloc.py @@ -1166,8 +1166,6 @@ self.Perform(op, [base_loc, ofs, itemsize, fieldsize, index_loc, temp_loc, sign_loc], result_loc) - consider_getinteriorfield_raw = consider_getinteriorfield_gc - def consider_int_is_true(self, op, guard_op): # doesn't need arg to be in a register argloc = self.loc(op.getarg(0)) 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 @@ -363,6 +363,7 @@ rop.DEBUG_MERGE_POINT, rop.JIT_DEBUG, rop.SETARRAYITEM_RAW, + rop.SETINTERIORFIELD_RAW, rop.CALL_RELEASE_GIL, rop.QUASIIMMUT_FIELD, rop.CALL_MALLOC_GC, 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 @@ -120,12 +120,6 @@ ops = self.do_push_arg(op) elif oopspec == EffectInfo.OS_LIBFFI_CALL: ops = self.do_call(op) - elif (oopspec == EffectInfo.OS_LIBFFI_STRUCT_GETFIELD or - oopspec == EffectInfo.OS_LIBFFI_STRUCT_SETFIELD): - ops = self.do_struct_getsetfield(op, oopspec) - 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) @@ -200,97 +194,6 @@ ops.append(newop) return ops - def do_struct_getsetfield(self, op, oopspec): - ffitypeval = self.getvalue(op.getarg(1)) - addrval = self.getvalue(op.getarg(2)) - offsetval = self.getvalue(op.getarg(3)) - if not ffitypeval.is_constant() or not offsetval.is_constant(): - return [op] - # - ffitypeaddr = ffitypeval.box.getaddr() - ffitype = llmemory.cast_adr_to_ptr(ffitypeaddr, clibffi.FFI_TYPE_P) - offset = offsetval.box.getint() - descr = self._get_field_descr(ffitype, offset) - # - arglist = [addrval.force_box(self.optimizer)] - if oopspec == EffectInfo.OS_LIBFFI_STRUCT_GETFIELD: - opnum = rop.GETFIELD_RAW - else: - opnum = rop.SETFIELD_RAW - newval = self.getvalue(op.getarg(4)) - arglist.append(newval.force_box(self.optimizer)) - # - newop = ResOperation(opnum, arglist, op.result, descr=descr) - return [newop] - - def _get_field_descr(self, ffitype, offset): - kind = libffi.types.getkind(ffitype) - is_pointer = is_float = is_signed = False - if ffitype is libffi.types.pointer: - is_pointer = True - elif kind == 'i': - is_signed = True - elif kind == 'f' or kind == 'I' or kind == 'U': - # longlongs are treated as floats, see e.g. llsupport/descr.py:getDescrClass - is_float = True - else: - assert False, "unsupported ffitype or kind" - # - fieldsize = intmask(ffitype.c_size) - return self.optimizer.cpu.fielddescrof_dynamic(offset, fieldsize, - is_pointer, is_float, is_signed) - - def do_getsetarrayitem(self, op, oopspec): - ffitypeval = self.getvalue(op.getarg(1)) - widthval = self.getvalue(op.getarg(2)) - offsetval = self.getvalue(op.getarg(5)) - if not ffitypeval.is_constant() or not widthval.is_constant() or not offsetval.is_constant(): - return [op] - - ffitypeaddr = ffitypeval.box.getaddr() - ffitype = llmemory.cast_adr_to_ptr(ffitypeaddr, clibffi.FFI_TYPE_P) - offset = offsetval.box.getint() - width = widthval.box.getint() - descr = self._get_interior_descr(ffitype, width, offset) - - arglist = [ - 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)) - else: - assert False - return [ - ResOperation(opnum, arglist, op.result, descr=descr), - ] - - def _get_interior_descr(self, ffitype, width, offset): - kind = libffi.types.getkind(ffitype) - is_pointer = is_float = is_signed = False - if ffitype is libffi.types.pointer: - is_pointer = True - elif kind == 'i': - is_signed = True - elif kind == 'f' or kind == 'I' or kind == 'U': - # longlongs are treated as floats, see - # e.g. llsupport/descr.py:getDescrClass - is_float = True - elif kind == 'u' or kind == 's': - # they're all False - pass - else: - raise NotImplementedError("unsupported ffitype or kind: %s" % kind) - # - fieldsize = rffi.getintfield(ffitype, 'c_size') - return self.optimizer.cpu.interiorfielddescrof_dynamic( - offset, width, fieldsize, is_pointer, is_float, is_signed - ) - - def propagate_forward(self, op): if self.logops is not None: debug_print(self.logops.repr_of_resop(op)) 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 @@ -490,6 +490,7 @@ 'SETARRAYITEM_GC/3d', 'SETARRAYITEM_RAW/3d', 'SETINTERIORFIELD_GC/3d', + 'SETINTERIORFIELD_RAW/3d', # only used by llsupport/rewrite.py 'RAW_STORE/3d', 'SETFIELD_GC/2d', 'SETFIELD_RAW/2d', diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py --- a/pypy/rlib/libffi.py +++ b/pypy/rlib/libffi.py @@ -432,127 +432,3 @@ flags=FUNCFLAG_STDCALL): return Func(name, argtypes, restype, dlsym_byordinal(self.lib, name), flags=flags, keepalive=self) - -# ====================================================================== - -@jit.oopspec('libffi_struct_getfield(ffitype, addr, offset)') -def struct_getfield_int(ffitype, addr, offset): - """ - Return the field of type ``ffitype`` at ``addr+offset``, widened to - lltype.Signed. - """ - for TYPE, ffitype2 in clibffi.ffitype_map_int_or_ptr: - if ffitype is ffitype2: - value = _struct_getfield(TYPE, addr, offset) - return rffi.cast(lltype.Signed, value) - assert False, "cannot find the given ffitype" - - -@jit.oopspec('libffi_struct_setfield(ffitype, addr, offset, value)') -def struct_setfield_int(ffitype, addr, offset, value): - """ - Set the field of type ``ffitype`` at ``addr+offset``. ``value`` is of - type lltype.Signed, and it's automatically converted to the right type. - """ - for TYPE, ffitype2 in clibffi.ffitype_map_int_or_ptr: - if ffitype is ffitype2: - value = rffi.cast(TYPE, value) - _struct_setfield(TYPE, addr, offset, value) - return - assert False, "cannot find the given ffitype" - - -@jit.oopspec('libffi_struct_getfield(ffitype, addr, offset)') -def struct_getfield_longlong(ffitype, addr, offset): - """ - Return the field of type ``ffitype`` at ``addr+offset``, casted to - lltype.LongLong. - """ - value = _struct_getfield(lltype.SignedLongLong, addr, offset) - return value - -@jit.oopspec('libffi_struct_setfield(ffitype, addr, offset, value)') -def struct_setfield_longlong(ffitype, addr, offset, value): - """ - Set the field of type ``ffitype`` at ``addr+offset``. ``value`` is of - type lltype.LongLong - """ - _struct_setfield(lltype.SignedLongLong, addr, offset, value) - - -@jit.oopspec('libffi_struct_getfield(ffitype, addr, offset)') -def struct_getfield_float(ffitype, addr, offset): - value = _struct_getfield(lltype.Float, addr, offset) - return value - -@jit.oopspec('libffi_struct_setfield(ffitype, addr, offset, value)') -def struct_setfield_float(ffitype, addr, offset, value): - _struct_setfield(lltype.Float, addr, offset, value) - - -@jit.oopspec('libffi_struct_getfield(ffitype, addr, offset)') -def struct_getfield_singlefloat(ffitype, addr, offset): - value = _struct_getfield(lltype.SingleFloat, addr, offset) - return value - -@jit.oopspec('libffi_struct_setfield(ffitype, addr, offset, value)') -def struct_setfield_singlefloat(ffitype, addr, offset, value): - _struct_setfield(lltype.SingleFloat, addr, offset, value) - - -@specialize.arg(0) -def _struct_getfield(TYPE, addr, offset): - """ - Read the field of type TYPE at addr+offset. - addr is of type rffi.VOIDP, offset is an int. - """ - addr = rffi.ptradd(addr, offset) - PTR_FIELD = lltype.Ptr(rffi.CArray(TYPE)) - return rffi.cast(PTR_FIELD, addr)[0] - - -@specialize.arg(0) -def _struct_setfield(TYPE, addr, offset, value): - """ - Write the field of type TYPE at addr+offset. - addr is of type rffi.VOIDP, offset is an int. - """ - addr = rffi.ptradd(addr, offset) - PTR_FIELD = lltype.Ptr(rffi.CArray(TYPE)) - rffi.cast(PTR_FIELD, addr)[0] = value - -# ====================================================================== - -# These specialize.call_location's should really be specialize.arg(0), however -# you can't hash a pointer obj, which the specialize machinery wants to do. -# Given the present usage of these functions, it's good enough. -@specialize.call_location() -@jit.oopspec("libffi_array_getitem(ffitype, width, addr, index, offset)") -def array_getitem(ffitype, width, addr, index, offset): - for TYPE, ffitype2 in clibffi.ffitype_map: - if ffitype is ffitype2: - addr = rffi.ptradd(addr, index * width) - addr = rffi.ptradd(addr, offset) - return rffi.cast(rffi.CArrayPtr(TYPE), addr)[0] - assert False - -def array_getitem_T(TYPE, width, addr, index, offset): - addr = rffi.ptradd(addr, index * width) - addr = rffi.ptradd(addr, offset) - return rffi.cast(rffi.CArrayPtr(TYPE), addr)[0] - -@specialize.call_location() -@jit.oopspec("libffi_array_setitem(ffitype, width, addr, index, offset, value)") -def array_setitem(ffitype, width, addr, index, offset, value): - for TYPE, ffitype2 in clibffi.ffitype_map: - if ffitype is ffitype2: - addr = rffi.ptradd(addr, index * width) - addr = rffi.ptradd(addr, offset) - rffi.cast(rffi.CArrayPtr(TYPE), addr)[0] = value - return - assert False - -def array_setitem_T(TYPE, width, addr, index, offset, value): - addr = rffi.ptradd(addr, index * width) - addr = rffi.ptradd(addr, offset) - rffi.cast(rffi.CArrayPtr(TYPE), addr)[0] = value _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit