Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: Changeset: r74352:27a0edfa55b5 Date: 2014-11-06 12:47 +0100 http://bitbucket.org/pypy/pypy/changeset/27a0edfa55b5/
Log: add a small fastpath for comparisons of a box with itself these either directly return true or false, depending on the comparison diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -33,6 +33,14 @@ # ____________________________________________________________ +FASTPATHS_SAME_BOXES = { + "ne": "history.CONST_FALSE", + "eq": "history.CONST_TRUE", + "lt": "history.CONST_FALSE", + "le": "history.CONST_TRUE", + "gt": "history.CONST_FALSE", + "ge": "history.CONST_TRUE", +} class MIFrame(object): debug = False @@ -188,8 +196,6 @@ # ------------------------------ for _opimpl in ['int_add', 'int_sub', 'int_mul', 'int_floordiv', 'int_mod', - 'int_lt', 'int_le', 'int_eq', - 'int_ne', 'int_gt', 'int_ge', 'int_and', 'int_or', 'int_xor', 'int_rshift', 'int_lshift', 'uint_rshift', 'uint_lt', 'uint_le', 'uint_gt', 'uint_ge', @@ -197,7 +203,6 @@ 'float_add', 'float_sub', 'float_mul', 'float_truediv', 'float_lt', 'float_le', 'float_eq', 'float_ne', 'float_gt', 'float_ge', - 'ptr_eq', 'ptr_ne', 'instance_ptr_eq', 'instance_ptr_ne', ]: exec py.code.Source(''' @arguments("box", "box") @@ -205,6 +210,18 @@ return self.execute(rop.%s, b1, b2) ''' % (_opimpl, _opimpl.upper())).compile() + for _opimpl in ['int_eq', 'int_ne', 'int_lt', 'int_le', 'int_gt', 'int_ge', + 'ptr_eq', 'ptr_ne', + 'instance_ptr_eq', 'instance_ptr_ne']: + exec py.code.Source(''' + @arguments("box", "box") + def opimpl_%s(self, b1, b2): + if b1 is b2: # crude fast check + return %s + return self.execute(rop.%s, b1, b2) + ''' % (_opimpl, FASTPATHS_SAME_BOXES[_opimpl.split("_")[-1]], _opimpl.upper()) + ).compile() + for _opimpl in ['int_add_ovf', 'int_sub_ovf', 'int_mul_ovf']: exec py.code.Source(''' @arguments("box", "box") @@ -340,10 +357,13 @@ exec py.code.Source(''' @arguments("box", "box", "label") def opimpl_goto_if_not_%s(self, b1, b2, target): - condbox = self.execute(rop.%s, b1, b2) + if b1 is b2: + condbox = %s + else: + condbox = self.execute(rop.%s, b1, b2) self.opimpl_goto_if_not(condbox, target) - ''' % (_opimpl, _opimpl.upper())).compile() - + ''' % (_opimpl, FASTPATHS_SAME_BOXES[_opimpl.split("_")[-1]], _opimpl.upper()) + ).compile() def _establish_nullity(self, box, orgpc): value = box.nonnull() diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -4119,3 +4119,64 @@ assert res == 42 res = self.interp_operations(f, [-42]) assert res == 0 + + def test_cmp_fastpaths(self): + class Z: pass + def make_int(cmp): + def f(x): + if cmp == 'eq': + return x == x and x == x + if cmp == 'ne': + return x != x or x != x + if cmp == 'lt': + return x < x or x != x + if cmp == 'le': + return x <= x and x <= x + if cmp == 'gt': + return x > x or x > x + if cmp == 'ge': + return x >= x and x >= x + assert 0 + return f + + def make_str(cmp): + def f(x): + x = str(x) + if cmp == 'eq': + return x is x or x is x + if cmp == 'ne': + return x is not x and x is not x + assert 0 + return f + + def make_object(cmp): + def f(x): + y = Z() + y.x = x + x = y + if cmp == 'eq': + return x is x + if cmp == 'ne': + return x is not x + assert 0 + return f + + for cmp in 'eq ne lt le gt ge'.split(): + f = make_int(cmp) + res = self.interp_operations(f, [42]) + assert res == f(42) + opname = "int_%s" % cmp + self.check_operations_history(**{opname: 0}) + + for cmp in 'eq ne'.split(): + f = make_str(cmp) + res = self.interp_operations(f, [42]) + assert res == f(42) + opname = "ptr_%s" % cmp + self.check_operations_history(**{opname: 0}) + + f = make_object(cmp) + res = self.interp_operations(f, [42]) + assert res == f(42) + opname = "instance_ptr_%s" % cmp + self.check_operations_history(**{opname: 0}) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit