[pypy-commit] pypy default: Detect and special-case in the JIT the greater-than kind of comparisons
arigo
noreply at buildbot.pypy.org
Mon Sep 1 12:04:09 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r73265:8b404466566d
Date: 2014-09-01 12:03 +0200
http://bitbucket.org/pypy/pypy/changeset/8b404466566d/
Log: Detect and special-case in the JIT the greater-than kind of
comparisons between two single characters (or unichars).
diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -36,6 +36,7 @@
OS_STREQ_NONNULL_CHAR = 29 # s1 == char (assert s1!=NULL)
OS_STREQ_CHECKNULL_CHAR = 30 # s1!=NULL and s1==char
OS_STREQ_LENGTHOK = 31 # s1 == s2 (assert len(s1)==len(s2))
+ OS_STR_CMP = 32 # "stroruni.cmp"
#
OS_UNI_CONCAT = 42 #
OS_UNI_SLICE = 43 #
@@ -47,6 +48,7 @@
OS_UNIEQ_NONNULL_CHAR = 49 # (must be the same amount as for
OS_UNIEQ_CHECKNULL_CHAR = 50 # STR, in the same order)
OS_UNIEQ_LENGTHOK = 51 #
+ OS_UNI_CMP = 52
_OS_offset_uni = OS_UNI_CONCAT - OS_STR_CONCAT
#
OS_LIBFFI_CALL = 62
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -1767,6 +1767,7 @@
dict = {"stroruni.concat": EffectInfo.OS_STR_CONCAT,
"stroruni.slice": EffectInfo.OS_STR_SLICE,
"stroruni.equal": EffectInfo.OS_STR_EQUAL,
+ "stroruni.cmp": EffectInfo.OS_STR_CMP,
"stroruni.copy_string_to_raw": EffectInfo.OS_STR_COPY_TO_RAW,
}
CHR = lltype.Char
@@ -1774,6 +1775,7 @@
dict = {"stroruni.concat": EffectInfo.OS_UNI_CONCAT,
"stroruni.slice": EffectInfo.OS_UNI_SLICE,
"stroruni.equal": EffectInfo.OS_UNI_EQUAL,
+ "stroruni.cmp": EffectInfo.OS_UNI_CMP,
"stroruni.copy_string_to_raw": EffectInfo.OS_UNI_COPY_TO_RAW
}
CHR = lltype.UniChar
diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py b/rpython/jit/metainterp/optimizeopt/vstring.py
--- a/rpython/jit/metainterp/optimizeopt/vstring.py
+++ b/rpython/jit/metainterp/optimizeopt/vstring.py
@@ -733,6 +733,25 @@
return True
return False
+ def opt_call_stroruni_STR_CMP(self, op, mode):
+ v1 = self.getvalue(op.getarg(1))
+ v2 = self.getvalue(op.getarg(2))
+ l1box = v1.getstrlen(None, mode, None)
+ l2box = v2.getstrlen(None, mode, None)
+ if (l1box is not None and l2box is not None and
+ isinstance(l1box, ConstInt) and
+ isinstance(l2box, ConstInt) and
+ l1box.value == l2box.value == 1):
+ # comparing two single chars
+ vchar1 = self.strgetitem(v1, optimizer.CVAL_ZERO, mode)
+ vchar2 = self.strgetitem(v2, optimizer.CVAL_ZERO, mode)
+ seo = self.optimizer.send_extra_operation
+ seo(ResOperation(rop.INT_SUB, [vchar1.force_box(self),
+ vchar2.force_box(self)],
+ op.result))
+ return True
+ return False
+
def opt_call_SHRINK_ARRAY(self, op):
v1 = self.getvalue(op.getarg(1))
v2 = self.getvalue(op.getarg(2))
diff --git a/rpython/jit/metainterp/test/test_string.py b/rpython/jit/metainterp/test/test_string.py
--- a/rpython/jit/metainterp/test/test_string.py
+++ b/rpython/jit/metainterp/test/test_string.py
@@ -846,6 +846,27 @@
'jump': 1, 'guard_true': 2, 'int_ge': 2, 'int_add': 2, 'int_sub': 2
})
+ def test_compare_single_char_for_ordering(self):
+ jitdriver = JitDriver(reds=['result', 'n'], greens=[])
+ _str = self._str
+ constant1 = _str("abcdefghij")
+
+ def cmpstr(x, y):
+ return x > _str(y)
+
+ def f(n):
+ cmpstr(_str("abc"), "def") # force x and y to be annot as strings
+ result = 0
+ while n >= 0:
+ jitdriver.jit_merge_point(n=n, result=result)
+ c = constant1[n]
+ result += cmpstr(c, "c")
+ n -= 1
+ return result
+
+ res = self.meta_interp(f, [9])
+ assert res == f(9)
+ self.check_resops(newstr=0, newunicode=0, call=0)
class TestLLtype(StringTests, LLJitMixin):
diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -531,6 +531,7 @@
return diff
i += 1
return len1 - len2
+ ll_strcmp.oopspec = 'stroruni.cmp(s1, s2)'
@jit.elidable
def ll_streq(s1, s2):
More information about the pypy-commit
mailing list