Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: record-known-result
Changeset: r97697:0085d3e74e02
Date: 2019-10-01 15:51 +0200
http://bitbucket.org/pypy/pypy/changeset/0085d3e74e02/
Log: tell the jit that the result of str.find is always smaller than the
length of the string
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
@@ -990,7 +990,48 @@
return len(d[s])
assert self.interp_operations(f, [222]) == 6
- def test_codepoint_index_at_byte_position_record_known_result(self):
+ def test_str_find(self):
+ jitdriver = JitDriver(greens=['x'], reds=['z', 'res'])
+ s1 = "aaaaaaef"
+ s2 = "aaaaaaaaaaaaaaaaaaaaeebbbbbbbbbbbbbbbbbbef"
+
+ @dont_look_inside
+ def pick(x):
+ if x > 0:
+ return s1
+ else:
+ return s2
+
+ @dont_look_inside
+ def pick_s(z):
+ if z < 5:
+ return "e"
+ return "ef"
+
+ def f(x):
+ z = 0
+ res = 0
+ while z < 10:
+ jitdriver.jit_merge_point(x=x, res=res, z=z)
+ s = pick(x)
+ # the following lines emulate unicode.find
+ byteindex = s.find(pick_s(x))
+ if byteindex < 0:
+ return -1001
+ if byteindex >= len(s): # no guard
+ return -106
+ res += ord(s[byteindex])
+ z += 1
+ return res
+ res = self.meta_interp(f, [1], backendopt=True)
+ assert res == f(1)
+ self.check_simple_loop(guard_false=1) # only one guard, to check for
-1
+ res = self.meta_interp(f, [10], backendopt=True)
+ assert res == f(10)
+ # one guard to check whether the search string is len == 1, one to
check for result -1
+ self.check_simple_loop(guard_false=2)
+
+ def
test_codepoint_index_at_byte_position_record_known_result_and_invariants(self):
from rpython.rlib import rutf8
jitdriver = JitDriver(greens=['x'], reds=['z', 'res'])
s1 = u"abceüf".encode("utf-8")
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
@@ -721,16 +721,22 @@
def ll_find(s1, s2, start, end):
if start < 0:
start = 0
- if end > len(s1.chars):
- end = len(s1.chars)
+ n = len(s1.chars)
+ if end > n:
+ end = n
if end - start < 0:
return -1
m = len(s2.chars)
if m == 1:
- return LLHelpers.ll_find_char(s1, s2.chars[0], start, end)
+ res = LLHelpers.ll_find_char(s1, s2.chars[0], start, end)
+ jit.record_exact_value(res < end, True)
+ return res
- return LLHelpers.ll_search(s1, s2, start, end, FAST_FIND)
+ res = LLHelpers.ll_search(s1, s2, start, end, FAST_FIND)
+ jit.record_exact_value(res < end, True)
+ jit.record_exact_value(res + m <= n, True)
+ return res
@staticmethod
@signature(types.any(), types.any(), types.int(), types.int(),
returns=types.int())
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit