[pypy-commit] pypy default: add a small fastpath for comparisons of a box with itself
cfbolz
noreply at buildbot.pypy.org
Thu Nov 6 12:51:53 CET 2014
Author: Carl Friedrich Bolz <cfbolz at 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})
More information about the pypy-commit
mailing list