[pypy-commit] pypy virtual-arguments: some more careful unrolling, start to write more test_pypy_c tests
fijal
noreply at buildbot.pypy.org
Sun Jul 15 19:01:00 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: virtual-arguments
Changeset: r56083:10f43a794c15
Date: 2012-07-15 19:00 +0200
http://bitbucket.org/pypy/pypy/changeset/10f43a794c15/
Log: some more careful unrolling, start to write more test_pypy_c tests
diff --git a/pypy/jit/metainterp/test/test_dict.py b/pypy/jit/metainterp/test/test_dict.py
--- a/pypy/jit/metainterp/test/test_dict.py
+++ b/pypy/jit/metainterp/test/test_dict.py
@@ -161,6 +161,22 @@
'guard_no_exception': 8, 'new': 2,
'guard_false': 2, 'int_is_true': 2})
+ def test_unrolling_of_dict_iter(self):
+ driver = JitDriver(greens = [], reds = ['n'])
+
+ def f(n):
+ while n > 0:
+ driver.jit_merge_point(n=n)
+ d = {1: 1}
+ for elem in d:
+ n -= elem
+ return n
+
+ res = self.meta_interp(f, [10], listops=True)
+ assert res == 0
+ self.check_simple_loop({'int_sub': 1, 'int_gt': 1, 'guard_true': 1,
+ 'jump': 1})
+
class TestOOtype(DictTests, OOJitMixin):
pass
diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py b/pypy/module/pypyjit/test_pypy_c/test_call.py
--- a/pypy/module/pypyjit/test_pypy_c/test_call.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_call.py
@@ -546,3 +546,58 @@
''')
assert len([op for op in allops if op.name.startswith('new')]) == 1
# 1 alloc
+
+ def test_complex_case(self):
+ log = self.run("""
+ def f(x, y, a, b, c=3, d=4):
+ pass
+
+ def main(stop):
+ i = 0
+ while i < stop:
+ a = [1, 2]
+ d = {'a': 2, 'b': 3, 'd':4}
+ f(*a, **d) # ID: call
+ i += 1
+ return 13
+ """, [1000])
+ loop, = log.loops_by_id('call')
+ allops = loop.allops()
+ calls = [op for op in allops if op.name.startswith('call')]
+ assert OpMatcher(calls).match('''
+ p93 = call(ConstClass(StringDictStrategy.view_as_kwargs), p35, p12, descr=<.*>)
+ i103 = call(ConstClass(_match_keywords), ConstPtr(ptr52), 0, 0, p94, p98, 0, descr=<.*>)
+ ''')
+ assert len([op for op in allops if op.name.startswith('new')]) == 1
+ # 1 alloc
+
+ def test_complex_case_global(self):
+ log = self.run("""
+ def f(x, y, a, b, c=3, d=4):
+ pass
+
+ a = [1, 2]
+ d = {'a': 2, 'b': 3, 'd':4}
+
+ def main(stop):
+ i = 0
+ while i < stop:
+ f(*a, **d) # ID: call
+ i += 1
+ return 13
+ """, [1000])
+
+ def test_complex_case_loopconst(self):
+ log = self.run("""
+ def f(x, y, a, b, c=3, d=4):
+ pass
+
+ def main(stop):
+ i = 0
+ a = [1, 2]
+ d = {'a': 2, 'b': 3, 'd':4}
+ while i < stop:
+ f(*a, **d) # ID: call
+ i += 1
+ return 13
+ """, [1000])
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -511,7 +511,7 @@
def w_keys(self, w_dict):
return self.space.newlist_str(self.listview_str(w_dict))
- @jit.look_inside_iff(lambda self, w_dict : jit.isvirtual(w_dict))
+ @jit.look_inside_iff(jit.w_dict_unrolling_heuristic)
def view_as_kwargs(self, w_dict):
d = self.unerase(w_dict.dstorage)
l = len(d)
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -214,6 +214,17 @@
"""
return isvirtual(lst) or (isconstant(size) and size <= LIST_CUTOFF)
+DICT_CUTOFF = 5
+
+ at specialize.call_location()
+def w_dict_unrolling_heurisitc(w_dct):
+ """ In which cases iterating over dict items can be unrolled.
+ Note that w_dct is an instance of W_DictMultiObject, not necesarilly
+ an actual dict
+ """
+ return isvirtual(w_dct) or (isconstant(w_dct) and
+ w_dct.length() <= DICT_CUTOFF)
+
class Entry(ExtRegistryEntry):
_about_ = hint
diff --git a/pypy/rpython/lltypesystem/rdict.py b/pypy/rpython/lltypesystem/rdict.py
--- a/pypy/rpython/lltypesystem/rdict.py
+++ b/pypy/rpython/lltypesystem/rdict.py
@@ -713,6 +713,10 @@
def _make_ll_dictnext(kind):
# make three versions of the following function: keys, values, items
+ @jit.look_inside_iff(lambda RETURNTYPE, iter: jit.isvirtual(iter)
+ and (iter.dict is None or
+ jit.isvirtual(iter.dict)))
+ @jit.oopspec("dictiter.next%s(iter)" % kind)
def ll_dictnext(RETURNTYPE, iter):
# note that RETURNTYPE is None for keys and values
dict = iter.dict
@@ -740,7 +744,6 @@
# clear the reference to the dict and prevent restarts
iter.dict = lltype.nullptr(lltype.typeOf(iter).TO.dict.TO)
raise StopIteration
- ll_dictnext.oopspec = 'dictiter.next%s(iter)' % kind
return ll_dictnext
ll_dictnext_group = {'keys' : _make_ll_dictnext('keys'),
More information about the pypy-commit
mailing list