[pypy-commit] pypy virtual-dicts: merged in default
alex_gaynor
noreply at buildbot.pypy.org
Mon Oct 24 21:32:13 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: virtual-dicts
Changeset: r48391:71c19063db1e
Date: 2011-10-24 15:32 -0400
http://bitbucket.org/pypy/pypy/changeset/71c19063db1e/
Log: merged in default
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
@@ -164,6 +164,7 @@
_is_array_of_pointers = False # unless overridden by GcPtrArrayDescr
_is_array_of_floats = False # unless overridden by FloatArrayDescr
+ _is_array_of_structs = False # unless overridden by StructArrayDescr
_is_item_signed = False # unless overridden by XxxArrayDescr
def is_array_of_pointers(self):
@@ -172,6 +173,9 @@
def is_array_of_floats(self):
return self._is_array_of_floats
+ def is_array_of_structs(self):
+ return self._is_array_of_structs
+
def is_item_signed(self):
return self._is_item_signed
@@ -196,6 +200,10 @@
def get_item_size(self, translate_support_code):
return symbolic.get_size(lltype.Float, translate_support_code)
+class StructArrayDescr(BaseArrayDescr):
+ _clsname = 'StructArrayDescr'
+ _is_array_of_structs = True
+
class BaseArrayNoLengthDescr(BaseArrayDescr):
def get_base_size(self, translate_support_code):
return 0
@@ -215,6 +223,13 @@
def getArrayDescrClass(ARRAY):
if ARRAY.OF is lltype.Float:
return FloatArrayDescr
+ elif isinstance(ARRAY.OF, lltype.Struct):
+ class Descr(StructArrayDescr):
+ _clsname = '%sArrayDescr' % ARRAY.OF._name
+ def get_item_size(self, translate_support_code):
+ return symbolic.get_size(ARRAY.OF, translate_support_code)
+ Descr.__name__ = Descr._clsname
+ return Descr
return getDescrClass(ARRAY.OF, BaseArrayDescr, GcPtrArrayDescr,
NonGcPtrArrayDescr, 'Array', 'get_item_size',
'_is_array_of_floats', '_is_item_signed')
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
@@ -1276,8 +1276,8 @@
genop_int_ne = _cmpop("NE", "NE")
genop_int_gt = _cmpop("G", "L")
genop_int_ge = _cmpop("GE", "LE")
- genop_ptr_eq = genop_int_eq
- genop_ptr_ne = genop_int_ne
+ genop_ptr_eq = genop_instance_ptr_eq = genop_int_eq
+ genop_ptr_ne = genop_instance_ptr_ne = genop_int_ne
genop_float_lt = _cmpop_float('B', 'A')
genop_float_le = _cmpop_float('BE', 'AE')
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
@@ -651,8 +651,8 @@
consider_uint_lt = _consider_compop
consider_uint_le = _consider_compop
consider_uint_ge = _consider_compop
- consider_ptr_eq = _consider_compop
- consider_ptr_ne = _consider_compop
+ consider_ptr_eq = consider_instance_ptr_eq = _consider_compop
+ consider_ptr_ne = consider_instance_ptr_ne = _consider_compop
def _consider_float_op(self, op):
loc1 = self.xrm.loc(op.getarg(1))
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
@@ -443,6 +443,8 @@
rewrite_op_gc_identityhash = _do_builtin_call
rewrite_op_gc_id = _do_builtin_call
rewrite_op_uint_mod = _do_builtin_call
+ rewrite_op_cast_float_to_uint = _do_builtin_call
+ rewrite_op_cast_uint_to_float = _do_builtin_call
# ----------
# getfield/setfield/mallocs etc.
@@ -798,6 +800,9 @@
def _is_gc(self, v):
return getattr(getattr(v.concretetype, "TO", None), "_gckind", "?") == 'gc'
+ def _is_rclass_instance(self, v):
+ return lltype._castdepth(v.concretetype.TO, rclass.OBJECT) >= 0
+
def _rewrite_cmp_ptrs(self, op):
if self._is_gc(op.args[0]):
return op
@@ -815,11 +820,21 @@
return self._rewrite_equality(op, 'int_is_true')
def rewrite_op_ptr_eq(self, op):
- op1 = self._rewrite_equality(op, 'ptr_iszero')
+ prefix = ''
+ if self._is_rclass_instance(op.args[0]):
+ assert self._is_rclass_instance(op.args[1])
+ op = SpaceOperation('instance_ptr_eq', op.args, op.result)
+ prefix = 'instance_'
+ op1 = self._rewrite_equality(op, prefix + 'ptr_iszero')
return self._rewrite_cmp_ptrs(op1)
def rewrite_op_ptr_ne(self, op):
- op1 = self._rewrite_equality(op, 'ptr_nonzero')
+ prefix = ''
+ if self._is_rclass_instance(op.args[0]):
+ assert self._is_rclass_instance(op.args[1])
+ op = SpaceOperation('instance_ptr_ne', op.args, op.result)
+ prefix = 'instance_'
+ op1 = self._rewrite_equality(op, prefix + 'ptr_nonzero')
return self._rewrite_cmp_ptrs(op1)
rewrite_op_ptr_iszero = _rewrite_cmp_ptrs
@@ -848,26 +863,44 @@
elif not float_arg and float_res:
# some int -> some float
ops = []
- v1 = varoftype(lltype.Signed)
- oplist = self.rewrite_operation(
- SpaceOperation('force_cast', [v_arg], v1)
- )
- if oplist:
- ops.extend(oplist)
+ v2 = varoftype(lltype.Float)
+ sizesign = rffi.size_and_sign(v_arg.concretetype)
+ if sizesign <= rffi.size_and_sign(lltype.Signed):
+ # cast from a type that fits in an int: either the size is
+ # smaller, or it is equal and it is not unsigned
+ v1 = varoftype(lltype.Signed)
+ oplist = self.rewrite_operation(
+ SpaceOperation('force_cast', [v_arg], v1)
+ )
+ if oplist:
+ ops.extend(oplist)
+ else:
+ v1 = v_arg
+ op = self.rewrite_operation(
+ SpaceOperation('cast_int_to_float', [v1], v2)
+ )
+ ops.append(op)
else:
- v1 = v_arg
- v2 = varoftype(lltype.Float)
- op = self.rewrite_operation(
- SpaceOperation('cast_int_to_float', [v1], v2)
- )
- ops.append(op)
+ if sizesign == rffi.size_and_sign(lltype.Unsigned):
+ opname = 'cast_uint_to_float'
+ elif sizesign == rffi.size_and_sign(lltype.SignedLongLong):
+ opname = 'cast_longlong_to_float'
+ elif sizesign == rffi.size_and_sign(lltype.UnsignedLongLong):
+ opname = 'cast_ulonglong_to_float'
+ else:
+ raise AssertionError('cast_x_to_float: %r' % (sizesign,))
+ ops1 = self.rewrite_operation(
+ SpaceOperation(opname, [v_arg], v2)
+ )
+ if not isinstance(ops1, list): ops1 = [ops1]
+ ops.extend(ops1)
op2 = self.rewrite_operation(
SpaceOperation('force_cast', [v2], v_result)
)
if op2:
ops.append(op2)
else:
- op.result = v_result
+ ops[-1].result = v_result
return ops
elif float_arg and not float_res:
# some float -> some int
@@ -880,18 +913,36 @@
ops.append(op1)
else:
v1 = v_arg
- v2 = varoftype(lltype.Signed)
- op = self.rewrite_operation(
- SpaceOperation('cast_float_to_int', [v1], v2)
- )
- ops.append(op)
- oplist = self.rewrite_operation(
- SpaceOperation('force_cast', [v2], v_result)
- )
- if oplist:
- ops.extend(oplist)
+ sizesign = rffi.size_and_sign(v_result.concretetype)
+ if sizesign <= rffi.size_and_sign(lltype.Signed):
+ # cast to a type that fits in an int: either the size is
+ # smaller, or it is equal and it is not unsigned
+ v2 = varoftype(lltype.Signed)
+ op = self.rewrite_operation(
+ SpaceOperation('cast_float_to_int', [v1], v2)
+ )
+ ops.append(op)
+ oplist = self.rewrite_operation(
+ SpaceOperation('force_cast', [v2], v_result)
+ )
+ if oplist:
+ ops.extend(oplist)
+ else:
+ op.result = v_result
else:
- op.result = v_result
+ if sizesign == rffi.size_and_sign(lltype.Unsigned):
+ opname = 'cast_float_to_uint'
+ elif sizesign == rffi.size_and_sign(lltype.SignedLongLong):
+ opname = 'cast_float_to_longlong'
+ elif sizesign == rffi.size_and_sign(lltype.UnsignedLongLong):
+ opname = 'cast_float_to_ulonglong'
+ else:
+ raise AssertionError('cast_float_to_x: %r' % (sizesign,))
+ ops1 = self.rewrite_operation(
+ SpaceOperation(opname, [v1], v_result)
+ )
+ if not isinstance(ops1, list): ops1 = [ops1]
+ ops.extend(ops1)
return ops
else:
assert False
@@ -1097,8 +1148,6 @@
# The new operation is optionally further processed by rewrite_operation().
for _old, _new in [('bool_not', 'int_is_zero'),
('cast_bool_to_float', 'cast_int_to_float'),
- ('cast_uint_to_float', 'cast_int_to_float'),
- ('cast_float_to_uint', 'cast_float_to_int'),
('int_add_nonneg_ovf', 'int_add_ovf'),
('keepalive', '-live-'),
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -229,6 +229,17 @@
else:
return x
+def _ll_1_cast_uint_to_float(x):
+ # XXX on 32-bit platforms, this should be done using cast_longlong_to_float
+ # (which is a residual call right now in the x86 backend)
+ return llop.cast_uint_to_float(lltype.Float, x)
+
+def _ll_1_cast_float_to_uint(x):
+ # XXX on 32-bit platforms, this should be done using cast_float_to_longlong
+ # (which is a residual call right now in the x86 backend)
+ return llop.cast_float_to_uint(lltype.Unsigned, x)
+
+
# math support
# ------------
diff --git a/pypy/jit/codewriter/test/test_flatten.py b/pypy/jit/codewriter/test/test_flatten.py
--- a/pypy/jit/codewriter/test/test_flatten.py
+++ b/pypy/jit/codewriter/test/test_flatten.py
@@ -8,7 +8,7 @@
from pypy.rpython.lltypesystem import lltype, rclass, rstr
from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
from pypy.translator.unsimplify import varoftype
-from pypy.rlib.rarithmetic import ovfcheck, r_uint
+from pypy.rlib.rarithmetic import ovfcheck, r_uint, r_longlong, r_ulonglong
from pypy.rlib.jit import dont_look_inside, _we_are_jitted, JitDriver
from pypy.rlib.objectmodel import keepalive_until_here
from pypy.rlib import jit
@@ -70,7 +70,8 @@
return 'residual'
def getcalldescr(self, op, oopspecindex=None, extraeffect=None):
try:
- if 'cannot_raise' in op.args[0].value._obj.graph.name:
+ name = op.args[0].value._obj._name
+ if 'cannot_raise' in name or name.startswith('cast_'):
return self._descr_cannot_raise
except AttributeError:
pass
@@ -900,6 +901,67 @@
int_return %i4
""", transform=True)
+ def f(dbl):
+ return rffi.cast(rffi.UCHAR, dbl)
+ self.encoding_test(f, [12.456], """
+ cast_float_to_int %f0 -> %i0
+ int_and %i0, $255 -> %i1
+ int_return %i1
+ """, transform=True)
+
+ def f(dbl):
+ return rffi.cast(lltype.Unsigned, dbl)
+ self.encoding_test(f, [12.456], """
+ residual_call_irf_i $<* fn cast_float_to_uint>, <Descr>, I[], R[], F[%f0] -> %i0
+ int_return %i0
+ """, transform=True)
+
+ def f(i):
+ return rffi.cast(lltype.Float, chr(i)) # "char -> float"
+ self.encoding_test(f, [12], """
+ cast_int_to_float %i0 -> %f0
+ float_return %f0
+ """, transform=True)
+
+ def f(i):
+ return rffi.cast(lltype.Float, r_uint(i)) # "uint -> float"
+ self.encoding_test(f, [12], """
+ residual_call_irf_f $<* fn cast_uint_to_float>, <Descr>, I[%i0], R[], F[] -> %f0
+ float_return %f0
+ """, transform=True)
+
+ if not longlong.is_64_bit:
+ def f(dbl):
+ return rffi.cast(lltype.SignedLongLong, dbl)
+ self.encoding_test(f, [12.3], """
+ residual_call_irf_f $<* fn llong_from_float>, <Descr>, I[], R[], F[%f0] -> %f1
+ float_return %f1
+ """, transform=True)
+
+ def f(dbl):
+ return rffi.cast(lltype.UnsignedLongLong, dbl)
+ self.encoding_test(f, [12.3], """
+ residual_call_irf_f $<* fn ullong_from_float>, <Descr>, I[], R[], F[%f0] -> %f1
+ float_return %f1
+ """, transform=True)
+
+ def f(x):
+ ll = r_longlong(x)
+ return rffi.cast(lltype.Float, ll)
+ self.encoding_test(f, [12], """
+ residual_call_irf_f $<* fn llong_from_int>, <Descr>, I[%i0], R[], F[] -> %f0
+ residual_call_irf_f $<* fn llong_to_float>, <Descr>, I[], R[], F[%f0] -> %f1
+ float_return %f1
+ """, transform=True)
+
+ def f(x):
+ ll = r_ulonglong(x)
+ return rffi.cast(lltype.Float, ll)
+ self.encoding_test(f, [12], """
+ residual_call_irf_f $<* fn ullong_from_int>, <Descr>, I[%i0], R[], F[] -> %f0
+ residual_call_irf_f $<* fn ullong_u_to_float>, <Descr>, I[], R[], F[%f0] -> %f1
+ float_return %f1
+ """, transform=True)
def test_direct_ptradd(self):
from pypy.rpython.lltypesystem import rffi
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
@@ -576,10 +576,10 @@
assert op1.args == [v2]
def test_ptr_eq():
- v1 = varoftype(rclass.OBJECTPTR)
- v2 = varoftype(rclass.OBJECTPTR)
+ v1 = varoftype(lltype.Ptr(rstr.STR))
+ v2 = varoftype(lltype.Ptr(rstr.STR))
v3 = varoftype(lltype.Bool)
- c0 = const(lltype.nullptr(rclass.OBJECT))
+ c0 = const(lltype.nullptr(rstr.STR))
#
for opname, reducedname in [('ptr_eq', 'ptr_iszero'),
('ptr_ne', 'ptr_nonzero')]:
@@ -598,6 +598,31 @@
assert op1.opname == reducedname
assert op1.args == [v2]
+def test_instance_ptr_eq():
+ v1 = varoftype(rclass.OBJECTPTR)
+ v2 = varoftype(rclass.OBJECTPTR)
+ v3 = varoftype(lltype.Bool)
+ c0 = const(lltype.nullptr(rclass.OBJECT))
+
+ for opname, newopname, reducedname in [
+ ('ptr_eq', 'instance_ptr_eq', 'instance_ptr_iszero'),
+ ('ptr_ne', 'instance_ptr_ne', 'instance_ptr_nonzero')
+ ]:
+ op = SpaceOperation(opname, [v1, v2], v3)
+ op1 = Transformer().rewrite_operation(op)
+ assert op1.opname == newopname
+ assert op1.args == [v1, v2]
+
+ op = SpaceOperation(opname, [v1, c0], v3)
+ op1 = Transformer().rewrite_operation(op)
+ assert op1.opname == reducedname
+ assert op1.args == [v1]
+
+ op = SpaceOperation(opname, [c0, v1], v3)
+ op1 = Transformer().rewrite_operation(op)
+ assert op1.opname == reducedname
+ assert op1.args == [v1]
+
def test_nongc_ptr_eq():
v1 = varoftype(rclass.NONGCOBJECTPTR)
v2 = varoftype(rclass.NONGCOBJECTPTR)
diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py
--- a/pypy/jit/metainterp/blackhole.py
+++ b/pypy/jit/metainterp/blackhole.py
@@ -499,6 +499,12 @@
@arguments("r", returns="i")
def bhimpl_ptr_nonzero(a):
return bool(a)
+ @arguments("r", "r", returns="i")
+ def bhimpl_instance_ptr_eq(a, b):
+ return a == b
+ @arguments("r", "r", returns="i")
+ def bhimpl_instance_ptr_ne(a, b):
+ return a != b
@arguments("r", returns="r")
def bhimpl_cast_opaque_ptr(a):
return a
@@ -630,6 +636,9 @@
a = longlong.getrealfloat(a)
# note: we need to call int() twice to care for the fact that
# int(-2147483648.0) returns a long :-(
+ # we could also call intmask() instead of the outermost int(), but
+ # it's probably better to explicitly crash (by getting a long) if a
+ # non-translated version tries to cast a too large float to an int.
return int(int(a))
@arguments("i", returns="f")
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -173,6 +173,11 @@
"""
raise NotImplementedError
+ def is_array_of_structs(self):
+ """ Implement for array descr
+ """
+ raise NotImplementedError
+
def is_pointer_field(self):
""" Implement for field descr
"""
diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -337,7 +337,7 @@
def optimize_INT_IS_ZERO(self, op):
self._optimize_nullness(op, op.getarg(0), False)
- def _optimize_oois_ooisnot(self, op, expect_isnot):
+ def _optimize_oois_ooisnot(self, op, expect_isnot, instance):
value0 = self.getvalue(op.getarg(0))
value1 = self.getvalue(op.getarg(1))
if value0.is_virtual():
@@ -355,21 +355,28 @@
elif value0 is value1:
self.make_constant_int(op.result, not expect_isnot)
else:
- cls0 = value0.get_constant_class(self.optimizer.cpu)
- if cls0 is not None:
- cls1 = value1.get_constant_class(self.optimizer.cpu)
- if cls1 is not None and not cls0.same_constant(cls1):
- # cannot be the same object, as we know that their
- # class is different
- self.make_constant_int(op.result, expect_isnot)
- return
+ if instance:
+ cls0 = value0.get_constant_class(self.optimizer.cpu)
+ if cls0 is not None:
+ cls1 = value1.get_constant_class(self.optimizer.cpu)
+ if cls1 is not None and not cls0.same_constant(cls1):
+ # cannot be the same object, as we know that their
+ # class is different
+ self.make_constant_int(op.result, expect_isnot)
+ return
self.emit_operation(op)
+ def optimize_PTR_EQ(self, op):
+ self._optimize_oois_ooisnot(op, False, False)
+
def optimize_PTR_NE(self, op):
- self._optimize_oois_ooisnot(op, True)
+ self._optimize_oois_ooisnot(op, True, False)
- def optimize_PTR_EQ(self, op):
- self._optimize_oois_ooisnot(op, False)
+ def optimize_INSTANCE_PTR_EQ(self, op):
+ self._optimize_oois_ooisnot(op, False, True)
+
+ def optimize_INSTANCE_PTR_NE(self, op):
+ self._optimize_oois_ooisnot(op, True, True)
## def optimize_INSTANCEOF(self, op):
## value = self.getvalue(op.args[0])
@@ -448,6 +455,9 @@
if v2.is_constant() and v2.box.getint() == 1:
self.make_equal_to(op.result, v1)
return
+ elif v1.is_constant() and v1.box.getint() == 0:
+ self.make_constant_int(op.result, 0)
+ return
if v1.intbound.known_ge(IntBound(0, 0)) and v2.is_constant():
val = v2.box.getint()
if val & (val - 1) == 0 and val > 0: # val == 2**shift
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -508,13 +508,13 @@
ops = """
[p0]
guard_class(p0, ConstClass(node_vtable)) []
- i0 = ptr_ne(p0, NULL)
+ i0 = instance_ptr_ne(p0, NULL)
guard_true(i0) []
- i1 = ptr_eq(p0, NULL)
+ i1 = instance_ptr_eq(p0, NULL)
guard_false(i1) []
- i2 = ptr_ne(NULL, p0)
+ i2 = instance_ptr_ne(NULL, p0)
guard_true(i0) []
- i3 = ptr_eq(NULL, p0)
+ i3 = instance_ptr_eq(NULL, p0)
guard_false(i1) []
jump(p0)
"""
@@ -2026,7 +2026,7 @@
ops = """
[p1]
guard_class(p1, ConstClass(node_vtable2)) []
- i = ptr_ne(ConstPtr(myptr), p1)
+ i = instance_ptr_ne(ConstPtr(myptr), p1)
guard_true(i) []
jump(p1)
"""
@@ -2181,6 +2181,17 @@
"""
self.optimize_loop(ops, expected)
+ ops = """
+ [i0]
+ i1 = int_floordiv(0, i0)
+ jump(i1)
+ """
+ expected = """
+ [i0]
+ jump(0)
+ """
+ self.optimize_loop(ops, expected)
+
def test_fold_partially_constant_ops_ovf(self):
ops = """
[i0]
@@ -4789,6 +4800,18 @@
"""
self.optimize_strunicode_loop(ops, expected)
+ def test_ptr_eq_str_constant(self):
+ ops = """
+ []
+ i0 = ptr_eq(s"abc", s"\x00")
+ finish(i0)
+ """
+ expected = """
+ []
+ finish(0)
+ """
+ self.optimize_loop(ops, expected)
+
class TestLLtype(BaseTestOptimizeBasic, LLtypeMixin):
pass
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -2683,7 +2683,7 @@
ops = """
[p1]
guard_class(p1, ConstClass(node_vtable2)) []
- i = ptr_ne(ConstPtr(myptr), p1)
+ i = instance_ptr_ne(ConstPtr(myptr), p1)
guard_true(i) []
jump(p1)
"""
@@ -3331,7 +3331,7 @@
jump(p1, i1, i2, i6)
'''
self.optimize_loop(ops, expected, preamble)
-
+
# ----------
@@ -7280,7 +7280,7 @@
ops = """
[p1, p2]
setarrayitem_gc(p1, 2, 10, descr=arraydescr)
- setarrayitem_gc(p2, 3, 13, descr=arraydescr)
+ setarrayitem_gc(p2, 3, 13, descr=arraydescr)
call(0, p1, p2, 0, 0, 10, descr=arraycopydescr)
jump(p1, p2)
"""
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -165,7 +165,7 @@
if not we_are_translated():
for b in registers[count:]:
assert not oldbox.same_box(b)
-
+
def make_result_of_lastop(self, resultbox):
got_type = resultbox.type
@@ -199,7 +199,7 @@
'float_add', 'float_sub', 'float_mul', 'float_truediv',
'float_lt', 'float_le', 'float_eq',
'float_ne', 'float_gt', 'float_ge',
- 'ptr_eq', 'ptr_ne',
+ 'ptr_eq', 'ptr_ne', 'instance_ptr_eq', 'instance_ptr_ne',
]:
exec py.code.Source('''
@arguments("box", "box")
@@ -604,7 +604,7 @@
opimpl_setinteriorfield_gc_i = _opimpl_setinteriorfield_gc_any
opimpl_setinteriorfield_gc_f = _opimpl_setinteriorfield_gc_any
opimpl_setinteriorfield_gc_r = _opimpl_setinteriorfield_gc_any
-
+
@arguments("box", "descr")
def _opimpl_getfield_raw_any(self, box, fielddescr):
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
@@ -404,8 +404,8 @@
'FLOAT_TRUEDIV/2',
'FLOAT_NEG/1',
'FLOAT_ABS/1',
- 'CAST_FLOAT_TO_INT/1',
- 'CAST_INT_TO_FLOAT/1',
+ 'CAST_FLOAT_TO_INT/1', # don't use for unsigned ints; we would
+ 'CAST_INT_TO_FLOAT/1', # need some messy code in the backend
'CAST_FLOAT_TO_SINGLEFLOAT/1',
'CAST_SINGLEFLOAT_TO_FLOAT/1',
#
@@ -437,6 +437,8 @@
#
'PTR_EQ/2b',
'PTR_NE/2b',
+ 'INSTANCE_PTR_EQ/2b',
+ 'INSTANCE_PTR_NE/2b',
'CAST_OPAQUE_PTR/1b',
#
'ARRAYLEN_GC/1d',
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -3436,6 +3436,58 @@
res = self.meta_interp(f, [16])
assert res == f(16)
+ def test_ptr_eq(self):
+ myjitdriver = JitDriver(greens = [], reds = ["n", "x"])
+ class A(object):
+ def __init__(self, v):
+ self.v = v
+ def f(n, x):
+ while n > 0:
+ myjitdriver.jit_merge_point(n=n, x=x)
+ z = 0 / x
+ a1 = A("key")
+ a2 = A("\x00")
+ n -= [a1, a2][z].v is not a2.v
+ return n
+ res = self.meta_interp(f, [10, 1])
+ assert res == 0
+
+ def test_instance_ptr_eq(self):
+ myjitdriver = JitDriver(greens = [], reds = ["n", "i", "a1", "a2"])
+ class A(object):
+ pass
+ def f(n):
+ a1 = A()
+ a2 = A()
+ i = 0
+ while n > 0:
+ myjitdriver.jit_merge_point(n=n, i=i, a1=a1, a2=a2)
+ if n % 2:
+ a = a2
+ else:
+ a = a1
+ i += a is a1
+ n -= 1
+ return i
+ res = self.meta_interp(f, [10])
+ assert res == f(10)
+
+ def test_virtual_array_of_structs(self):
+ myjitdriver = JitDriver(greens = [], reds=["n", "d"])
+ def f(n):
+ d = None
+ while n > 0:
+ myjitdriver.jit_merge_point(n=n, d=d)
+ d = {}
+ if n % 2:
+ d["k"] = n
+ else:
+ d["z"] = n
+ n -= len(d)
+ return n
+ res = self.meta_interp(f, [10])
+ assert res == 0
+
def test_virtual_dict_constant_keys(self):
myjitdriver = JitDriver(greens = [], reds = ["n"])
def g(d):
@@ -3446,6 +3498,7 @@
myjitdriver.jit_merge_point(n=n)
n = g({"key": n})
return n
+
res = self.meta_interp(f, [10])
assert res == 0
self.check_loops({"int_sub": 1, "int_gt": 1, "guard_true": 1, "jump": 1})
diff --git a/pypy/jit/metainterp/test/test_float.py b/pypy/jit/metainterp/test/test_float.py
--- a/pypy/jit/metainterp/test/test_float.py
+++ b/pypy/jit/metainterp/test/test_float.py
@@ -1,5 +1,6 @@
-import math
+import math, sys
from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
+from pypy.rlib.rarithmetic import intmask, r_uint
class FloatTests:
@@ -45,6 +46,34 @@
res = self.interp_operations(f, [-2.0])
assert res == -8.5
+ def test_cast_float_to_int(self):
+ def g(f):
+ return int(f)
+ res = self.interp_operations(g, [-12345.9])
+ assert res == -12345
+
+ def test_cast_float_to_uint(self):
+ def g(f):
+ return intmask(r_uint(f))
+ res = self.interp_operations(g, [sys.maxint*2.0])
+ assert res == intmask(long(sys.maxint*2.0))
+ res = self.interp_operations(g, [-12345.9])
+ assert res == -12345
+
+ def test_cast_int_to_float(self):
+ def g(i):
+ return float(i)
+ res = self.interp_operations(g, [-12345])
+ assert type(res) is float and res == -12345.0
+
+ def test_cast_uint_to_float(self):
+ def g(i):
+ return float(r_uint(i))
+ res = self.interp_operations(g, [intmask(sys.maxint*2)])
+ assert type(res) is float and res == float(sys.maxint*2)
+ res = self.interp_operations(g, [-12345])
+ assert type(res) is float and res == float(long(r_uint(-12345)))
+
class TestOOtype(FloatTests, OOJitMixin):
pass
diff --git a/pypy/pytest.ini b/pypy/pytest.ini
--- a/pypy/pytest.ini
+++ b/pypy/pytest.ini
@@ -1,2 +1,2 @@
[pytest]
-addopts = --assertmode=old
\ No newline at end of file
+addopts = --assertmode=old -rf
diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py
--- a/pypy/rpython/llinterp.py
+++ b/pypy/rpython/llinterp.py
@@ -1095,13 +1095,6 @@
assert y >= 0
return self.op_int_add_ovf(x, y)
- def op_cast_float_to_int(self, f):
- assert type(f) is float
- try:
- return ovfcheck(int(f))
- except OverflowError:
- self.make_llexception()
-
def op_int_is_true(self, x):
# special case
if type(x) is CDefinedIntSymbolic:
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -343,8 +343,8 @@
'cast_uint_to_float': LLOp(canfold=True),
'cast_longlong_to_float' :LLOp(canfold=True),
'cast_ulonglong_to_float':LLOp(canfold=True),
- 'cast_float_to_int': LLOp(canraise=(OverflowError,), tryfold=True),
- 'cast_float_to_uint': LLOp(canfold=True), # XXX need OverflowError?
+ 'cast_float_to_int': LLOp(canfold=True),
+ 'cast_float_to_uint': LLOp(canfold=True),
'cast_float_to_longlong' :LLOp(canfold=True),
'cast_float_to_ulonglong':LLOp(canfold=True),
'truncate_longlong_to_int':LLOp(canfold=True),
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -355,6 +355,10 @@
assert type(b) is bool
return float(b)
+def op_cast_float_to_int(f):
+ assert type(f) is float
+ return intmask(int(f))
+
def op_cast_float_to_uint(f):
assert type(f) is float
return r_uint(long(f))
More information about the pypy-commit
mailing list