Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r49939:f2d0500eb97f Date: 2011-11-29 09:34 +0200 http://bitbucket.org/pypy/pypy/changeset/f2d0500eb97f/
Log: merge 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 @@ -1003,6 +1003,9 @@ insns = {} for loop in self.loops: insns = loop.summary(adding_insns=insns) + return self._check_insns(insns, expected, check) + + def _check_insns(self, insns, expected, check): if expected is not None: insns.pop('debug_merge_point', None) assert insns == expected @@ -1012,6 +1015,25 @@ assert found == expected_count, ( "found %d %r, expected %d" % (found, insn, expected_count)) return insns + + def check_simple_loop(self, expected=None, **check): + # Usefull in the simplest case when we have only one trace ending with + # a jump back to itself and possibly a few bridges ending with finnish. + # Only the operations within the loop formed by that single jump will + # be counted. + + # XXX hacked version, ignore and remove me when jit-targets is merged. + loops = self.get_all_loops() + loops = [loop for loop in loops if 'Preamble' not in repr(loop)] #XXX + assert len(loops) == 1 + loop, = loops + jumpop = loop.operations[-1] + assert jumpop.getopnum() == rop.JUMP + insns = {} + for op in loop.operations: + opname = op.getopname() + insns[opname] = insns.get(opname, 0) + 1 + return self._check_insns(insns, expected, check) def check_consistency(self): "NOT_RPYTHON" diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py --- a/pypy/jit/metainterp/test/support.py +++ b/pypy/jit/metainterp/test/support.py @@ -157,6 +157,8 @@ basic = True def check_resops(self, expected=None, **check): get_stats().check_resops(expected=expected, **check) + def check_simple_loop(self, expected=None, **check): + get_stats().check_simple_loop(expected=expected, **check) def check_loop_count(self, count): """NB. This is a hack; use check_tree_loop_count() or 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 @@ -107,7 +107,7 @@ res = self.meta_interp(f, [6, 7]) assert res == 1323 self.check_loop_count(1) - self.check_resops(int_mul=3) + self.check_simple_loop(int_mul=1) def test_loop_variant_mul_ovf(self): myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x']) @@ -124,7 +124,7 @@ res = self.meta_interp(f, [6, 7]) assert res == 1323 self.check_loop_count(1) - self.check_resops(int_mul_ovf=3) + self.check_simple_loop(int_mul_ovf=1) def test_loop_invariant_mul1(self): myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x']) @@ -139,6 +139,7 @@ res = self.meta_interp(f, [6, 7]) assert res == 252 self.check_loop_count(1) + self.check_simple_loop(int_mul=0) self.check_resops({'jump': 2, 'int_gt': 2, 'int_add': 2, 'int_mul': 1, 'guard_true': 2, 'int_sub': 2}) @@ -157,6 +158,7 @@ res = self.meta_interp(f, [6, 7]) assert res == 308 self.check_loop_count(1) + self.check_simple_loop(int_mul_ovf=0) self.check_resops({'jump': 2, 'int_lshift': 2, 'int_gt': 2, 'int_mul_ovf': 1, 'int_add': 4, 'guard_true': 2, 'guard_no_overflow': 1, diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py --- a/pypy/module/micronumpy/compile.py +++ b/pypy/module/micronumpy/compile.py @@ -97,7 +97,7 @@ return w_obj def float_w(self, w_obj): - assert isinstance(w_obj, FloatObject) + assert isinstance(w_obj, FloatObject) return w_obj.floatval def int_w(self, w_obj): @@ -251,7 +251,7 @@ elif self.name == '*': w_res = w_lhs.descr_mul(interp.space, w_rhs) elif self.name == '-': - w_res = w_lhs.descr_sub(interp.space, w_rhs) + w_res = w_lhs.descr_sub(interp.space, w_rhs) elif self.name == '->': assert not isinstance(w_rhs, Scalar) if isinstance(w_rhs, FloatObject): @@ -483,8 +483,8 @@ else: step = 1 return SliceConstant(start, stop, step) - - + + def parse_expression(self, tokens): stack = [] while tokens.remaining(): @@ -538,7 +538,7 @@ if token.name == 'array_right': return elems assert token.name == 'coma' - + def parse_statement(self, tokens): if (tokens.get(0).name == 'identifier' and tokens.get(1).name == 'assign'): diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py --- a/pypy/module/micronumpy/test/test_compile.py +++ b/pypy/module/micronumpy/test/test_compile.py @@ -177,6 +177,16 @@ """) assert interp.results[0].value.val == 6 + def test_setslice(self): + interp = self.run(""" + a = |30| + b = |10| + b[1] = 5 + a[::3] = b + a -> 3 + """) + assert interp.results[0].value.val == 5 + def test_multidim_getitem(self): interp = self.run(""" a = [[1,2]] diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py --- a/pypy/module/micronumpy/test/test_zjit.py +++ b/pypy/module/micronumpy/test/test_zjit.py @@ -80,10 +80,9 @@ def test_add(self): result = self.run("add") - self.check_resops({'setarrayitem_raw': 2, 'getfield_gc': 19, 'guard_class': 11, - 'int_add': 6, 'guard_isnull': 1, 'jump': 2, 'int_ge': 2, - 'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 2, - 'guard_value': 1}) + self.check_simple_loop({'getarrayitem_raw': 2, 'float_add': 1, + 'setarrayitem_raw': 1, 'int_add': 3, + 'int_ge': 1, 'guard_false': 1, 'jump': 1}) assert result == 3 + 3 def define_float_add(): @@ -95,10 +94,9 @@ def test_floatadd(self): result = self.run("float_add") assert result == 3 + 3 - self.check_resops({'setarrayitem_raw': 2, 'getfield_gc': 17, 'guard_class': 11, - 'int_add': 4, 'guard_isnull': 1, 'jump': 2, 'int_ge': 2, - 'getarrayitem_raw': 2, 'float_add': 2, 'guard_false': 2, - 'guard_value': 1}) + self.check_simple_loop({"getarrayitem_raw": 1, "float_add": 1, + "setarrayitem_raw": 1, "int_add": 2, + "int_ge": 1, "guard_false": 1, "jump": 1}) def define_sum(): return """ @@ -110,9 +108,9 @@ def test_sum(self): result = self.run("sum") assert result == 2 * sum(range(30)) - self.check_resops({'guard_class': 10, 'getfield_gc': 17, 'jump': 2, - 'getarrayitem_raw': 4, 'guard_value': 2, 'int_add': 4, - 'guard_isnull': 1, 'int_ge': 2, 'float_add': 4, 'guard_false': 2}) + self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 2, + "int_add": 2, + "int_ge": 1, "guard_false": 1, "jump": 1}) def define_prod(): return """ @@ -127,11 +125,9 @@ for i in range(30): expected *= i * 2 assert result == expected - self.check_resops({'guard_class': 10, 'getfield_gc': 17, 'int_add': 4, - 'float_mul': 2, 'guard_isnull': 1, 'jump': 2, 'int_ge': 2, - 'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 2, - 'guard_value': 2}) - + self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1, + "float_mul": 1, "int_add": 2, + "int_ge": 1, "guard_false": 1, "jump": 1}) def test_max(self): py.test.skip("broken, investigate") @@ -142,7 +138,7 @@ max(b) """) assert result == 256 - self.check_loops({"getarrayitem_raw": 2, "float_add": 1, + self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1, "float_mul": 1, "int_add": 1, "int_lt": 1, "guard_true": 1, "jump": 1}) @@ -155,10 +151,9 @@ min(b) """) assert result == -24 - self.check_resops({'guard_class': 10, 'getfield_gc': 15, 'guard_value': 1, - 'int_add': 4, 'guard_isnull': 1, 'jump': 2, 'int_ge': 2, - 'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 4, - 'float_ne': 2}) + self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1, + "float_mul": 1, "int_add": 1, + "int_lt": 1, "guard_true": 1, "jump": 1}) def define_any(): return """ @@ -171,10 +166,10 @@ def test_any(self): result = self.run("any") assert result == 1 - self.check_resops({'guard_class': 10, 'getfield_gc': 15, 'guard_value': 1, - 'int_add': 4, 'guard_isnull': 1, 'jump': 2, 'int_ge': 2, - 'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 4, - 'float_ne': 2}) + self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1, + "float_ne": 1, "int_add": 2, + "int_ge": 1, "jump": 1, + "guard_false": 2}) def define_already_forced(): return """ @@ -191,13 +186,14 @@ # This is the sum of the ops for both loops, however if you remove the # optimization then you end up with 2 float_adds, so we can still be # sure it was optimized correctly. + # XXX the comment above is wrong now. We need preferrably a way to + # count the two loops separately self.check_resops({'setarrayitem_raw': 4, 'guard_nonnull': 1, 'getfield_gc': 35, 'guard_class': 22, 'int_add': 8, 'float_mul': 2, 'guard_isnull': 2, 'jump': 4, 'int_ge': 4, 'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 4, 'guard_value': 2}) - def define_ufunc(): return """ a = |30| @@ -209,11 +205,10 @@ def test_ufunc(self): result = self.run("ufunc") assert result == -6 - self.check_resops({'setarrayitem_raw': 2, 'getfield_gc': 24, 'guard_class': 14, - 'int_add': 6, 'float_neg': 2, 'guard_isnull': 2, 'jump': 2, - 'int_ge': 2, 'getarrayitem_raw': 4, 'float_add': 2, - 'guard_false': 2, 'guard_value': 2}) - + self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1, "float_neg": 1, + "setarrayitem_raw": 1, "int_add": 3, + "int_ge": 1, "guard_false": 1, "jump": 1, + }) def define_specialization(): return """ @@ -252,7 +247,7 @@ result = self.run("slice") assert result == 18 py.test.skip("Few remaining arraylen_gc left") - self.check_loops({'int_mul': 2, 'getarrayitem_raw': 2, 'float_add': 1, + self.check_simple_loop({'int_mul': 2, 'getarrayitem_raw': 2, 'float_add': 1, 'setarrayitem_raw': 1, 'int_add': 3, 'int_lt': 1, 'guard_true': 1, 'jump': 1}) @@ -266,10 +261,9 @@ def test_multidim(self): result = self.run('multidim') assert result == 8 - self.check_resops({'setarrayitem_raw': 2, 'getfield_gc': 19, 'guard_class': 11, - 'int_add': 6, 'guard_isnull': 1, 'jump': 2, 'int_ge': 2, - 'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 2, - 'guard_value': 1}) + self.check_simple_loop({'float_add': 1, 'getarrayitem_raw': 2, + 'guard_false': 1, 'int_add': 3, 'int_ge': 1, + 'jump': 1, 'setarrayitem_raw': 1}) # int_add might be 1 here if we try slightly harder with # reusing indexes or some optimization @@ -287,7 +281,7 @@ py.test.skip("improve") # XXX the bridge here is scary. Hopefully jit-targets will fix that, # otherwise it looks kind of good - self.check_loops({}) + self.check_simple_loop({}) def define_broadcast(): return """ @@ -301,7 +295,25 @@ result = self.run("broadcast") assert result == 10 py.test.skip("improve") - self.check_loops({}) + self.check_simple_loop({}) + + def define_setslice(): + return """ + a = |30| + b = |10| + b[1] = 5.5 + c = b + b + a[0:30:3] = c + a -> 3 + """ + + def test_setslice(self): + result = self.run("setslice") + assert result == 11.0 + py.test.skip("generates 2 loops ATM, investigate") + self.check_simple_loop({'getarrayitem_raw': 2, 'float_add' : 1, + 'setarrayitem_raw': 1, 'int_add': 2, + 'int_lt': 1, 'guard_true': 1, 'jump': 1}) def define_set_slice(): return """ @@ -342,7 +354,7 @@ return v.get_concrete().eval(3).val result = self.meta_interp(f, [5], listops=True, backendopt=True) - self.check_loops({'int_mul': 2, 'getarrayitem_raw': 2, 'float_add': 1, + self.check_simple_loop({'int_mul': 2, 'getarrayitem_raw': 2, 'float_add': 1, 'setarrayitem_raw': 1, 'int_add': 1, 'int_lt': 1, 'guard_true': 1, 'jump': 1}) assert result == f(5) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit