Author: Alex Gaynor <[email protected]>
Branch: unroll-if-alt
Changeset: r47359:4c4ee51558ff
Date: 2011-09-19 20:40 -0400
http://bitbucket.org/pypy/pypy/changeset/4c4ee51558ff/
Log: Added jit.isvirtual, use it for RPYthon level "".join, and now a
test_pypy_c test for struct.pack and unpack.
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
@@ -1161,6 +1161,9 @@
elif oopspec_name == 'jit.isconstant':
kind = getkind(args[0].concretetype)
return SpaceOperation('%s_isconstant' % kind, args, op.result)
+ elif oopspec_name == 'jit.isvirtual':
+ kind = getkind(args[0].concretetype)
+ return SpaceOperation('%s_isvirtual' % kind, args, op.result)
else:
raise AssertionError("missing support for %r" % oopspec_name)
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
@@ -843,6 +843,10 @@
def bhimpl_ref_isconstant(x):
return False
+ @arguments("r", returns="i")
+ def bhimpl_ref_isvirtual(x):
+ return False
+
# ----------
# the main hints and recursive calls
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
@@ -1076,6 +1076,12 @@
opimpl_int_isconstant = opimpl_ref_isconstant = _opimpl_isconstant
@arguments("box")
+ def _opimpl_isvirtual(self, box):
+ return ConstInt(self.metainterp.heapcache.is_unescaped(box))
+
+ opimpl_ref_isvirtual = _opimpl_isvirtual
+
+ @arguments("box")
def opimpl_virtual_ref(self, box):
# Details on the content of metainterp.virtualref_boxes:
#
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
@@ -12,7 +12,8 @@
from pypy.jit.metainterp.warmstate import set_future_value
from pypy.rlib.jit import (JitDriver, we_are_jitted, hint, dont_look_inside,
loop_invariant, elidable, promote, jit_debug, assert_green,
- AssertGreenFailed, unroll_safe, current_trace_length, look_inside_iff,
isconstant)
+ AssertGreenFailed, unroll_safe, current_trace_length, look_inside_iff,
+ isconstant, isvirtual)
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
from pypy.rpython.ootypesystem import ootype
@@ -100,14 +101,14 @@
myjitdriver.jit_merge_point(x=x, y=y, res=res)
res += x * x
x += 1
- res += x * x
+ res += x * x
y -= 1
return res
res = self.meta_interp(f, [6, 7])
assert res == 1323
self.check_loop_count(1)
self.check_loops(int_mul=1)
-
+
def test_loop_variant_mul_ovf(self):
myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
def f(x, y):
@@ -1373,7 +1374,7 @@
return x
res = self.meta_interp(f, [299], listops=True)
assert res == f(299)
- self.check_loops(guard_class=0, guard_value=3)
+ self.check_loops(guard_class=0, guard_value=3)
self.check_loops(guard_class=0, guard_value=6, everywhere=True)
def test_merge_guardnonnull_guardclass(self):
@@ -2119,7 +2120,7 @@
return sa
res = self.meta_interp(f, [32, 7])
assert res == f(32, 7)
-
+
def test_caching_setarrayitem_fixed(self):
myjitdriver = JitDriver(greens = [], reds = ['sa', 'i', 'n', 'a',
'node'])
def f(n, a):
@@ -2139,7 +2140,7 @@
return sa
res = self.meta_interp(f, [32, 7])
assert res == f(32, 7)
-
+
def test_caching_setarrayitem_var(self):
myjitdriver = JitDriver(greens = [], reds = ['sa', 'i', 'n', 'a', 'b',
'node'])
def f(n, a, b):
@@ -2669,7 +2670,7 @@
myjitdriver.set_param('threshold', 3)
myjitdriver.set_param('trace_eagerness', 1)
myjitdriver.set_param('retrace_limit', 5)
- myjitdriver.set_param('function_threshold', -1)
+ myjitdriver.set_param('function_threshold', -1)
pc = sa = i = 0
while pc < len(bytecode):
myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i)
@@ -2694,12 +2695,12 @@
def g(n1, n2):
for i in range(10):
f(n1)
- for i in range(10):
+ for i in range(10):
f(n2)
nn = [10, 3]
assert self.meta_interp(g, nn) == g(*nn)
-
+
# The attempts of retracing first loop will end up retracing the
# second and thus fail 5 times, saturating the retrace_count. Instead a
# bridge back to the preamble of the first loop is produced. A guard in
@@ -2710,7 +2711,7 @@
self.check_tree_loop_count(2 + 3)
# FIXME: Add a gloabl retrace counter and test that we are not trying
more than 5 times.
-
+
def g(n):
for i in range(n):
for j in range(10):
@@ -2954,7 +2955,7 @@
res = self.meta_interp(f, [32])
assert res == f(32)
self.check_loops(arraylen_gc=2)
-
+
class TestOOtype(BasicTests, OOJitMixin):
def test_oohash(self):
@@ -3174,7 +3175,7 @@
res = self.meta_interp(f, [32])
assert res == f(32)
self.check_tree_loop_count(3)
-
+
def test_two_loopinvariant_arrays3(self):
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
myjitdriver = JitDriver(greens = [], reds = ['sa', 'n', 'i', 'a'])
@@ -3198,7 +3199,7 @@
res = self.meta_interp(f, [32])
assert res == f(32)
self.check_tree_loop_count(2)
-
+
def test_two_loopinvariant_arrays_boxed(self):
class A(object):
def __init__(self, a):
@@ -3223,7 +3224,7 @@
res = self.meta_interp(f, [32])
assert res == f(32)
self.check_loops(arraylen_gc=2, everywhere=True)
-
+
def test_release_gil_flush_heap_cache(self):
if sys.platform == "win32":
py.test.skip("needs 'time'")
@@ -3328,6 +3329,34 @@
assert res == main(1, 10, 2)
self.check_loops(call=0)
+ def test_look_inside_iff_virtual(self):
+ # There's no good reason for this to be look_inside_iff, but it's a
test!
+ @look_inside_iff(lambda arg, n: isvirtual(arg))
+ def f(arg, n):
+ if n == 100:
+ for i in xrange(n):
+ n += i
+ return arg.x
+ class A(object):
+ def __init__(self, x):
+ self.x = x
+ driver = JitDriver(greens=['n'], reds=['i', 'a'])
+ def main(n):
+ i = 0
+ a = A(3)
+ while i < 20:
+ driver.jit_merge_point(i=i, n=n, a=a)
+ if n == 0:
+ i += f(a, n)
+ else:
+ i += f(A(2), n)
+ res = self.meta_interp(main, [0], enable_opts='')
+ assert res == main(0)
+ self.check_loops(call=1, getfield_gc=0)
+ res = self.meta_interp(main, [1], enable_opts='')
+ assert res == main(1)
+ self.check_loops(call=0, getfield_gc=0)
+
def test_reuse_elidable_result(self):
driver = JitDriver(reds=['n', 's'], greens = [])
def main(n):
diff --git a/pypy/module/pypyjit/test_pypy_c/test_misc.py
b/pypy/module/pypyjit/test_pypy_c/test_misc.py
--- a/pypy/module/pypyjit/test_pypy_c/test_misc.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_misc.py
@@ -92,7 +92,7 @@
""")
- def test_cached_pure_func_of_equal_fields(self):
+ def test_cached_pure_func_of_equal_fields(self):
def main(n):
class A(object):
def __init__(self, val):
@@ -285,3 +285,42 @@
loop, = log.loops_by_id("globalread", is_entry_bridge=True)
assert len(loop.ops_by_id("globalread")) == 0
+
+ def test_struct_module(self):
+ def main():
+ import struct
+ i = 1
+ while i < 1000:
+ x = struct.unpack("i", struct.pack("i", i))[0] # ID: struct
+ i += x / i
+ return i
+
+ log = self.run(main)
+ assert log.result == main()
+
+ loop, = log.loops_by_id("struct")
+ # This could, of course stand some improvement, to remove all these
+ # arithmatic ops, but we've removed all the core overhead.
+ assert loop.match_by_id("struct", """
+ guard_not_invalidated(descr=...)
+ # struct.pack
+ i8 = int_lt(i4, -2147483648)
+ guard_false(i8, descr=...)
+ i11 = int_and(i4, 255)
+ i13 = int_rshift(i4, 8)
+ i14 = int_and(i13, 255)
+ i16 = int_rshift(i13, 8)
+ i17 = int_and(i16, 255)
+ i19 = int_rshift(i16, 8)
+ i20 = int_and(i19, 255)
+
+ # struct.unpack
+ i22 = int_lshift(i14, 8)
+ i23 = int_or(i11, i22)
+ i25 = int_lshift(i17, 16)
+ i26 = int_or(i23, i25)
+ i28 = int_ge(i20, 128)
+ guard_false(i28, descr=...)
+ i30 = int_lshift(i20, 24)
+ i31 = int_or(i26, i30)
+ """)
\ No newline at end of file
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -165,6 +165,17 @@
return True
return False
+@oopspec("jit.isvirtual(value)")
[email protected]()
+def isvirtual(value):
+ """
+ Returns if this value is virtual, while tracing, it's relatively
+ conservative and will miss some cases.
+ """
+ if NonConstant(False):
+ return True
+ return False
+
class Entry(ExtRegistryEntry):
_about_ = hint
diff --git a/pypy/rpython/lltypesystem/rstr.py
b/pypy/rpython/lltypesystem/rstr.py
--- a/pypy/rpython/lltypesystem/rstr.py
+++ b/pypy/rpython/lltypesystem/rstr.py
@@ -728,6 +728,7 @@
i += 1
return result
+ @jit.look_inside_iff(lambda length, chars, RES: jit.isconstant(length) and
jit.isvirtual(chars))
def ll_join_chars(length, chars, RES):
# no need to optimize this, will be replaced by string builder
# at some point soon
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit