Author: Maciej Fijalkowski <fij...@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 + +@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'), _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit