[pypy-commit] pypy record-known-result: optimize int(str(i)) and same for rbigints. (Note that the other direction is
cfbolz
pypy.commits at gmail.com
Sat Feb 8 05:19:02 EST 2020
Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: record-known-result
Changeset: r98682:452d076e43fa
Date: 2020-02-06 23:55 +0100
http://bitbucket.org/pypy/pypy/changeset/452d076e43fa/
Log: optimize int(str(i)) and same for rbigints. (Note that the other
direction is not necessarily correct, because int(" 123") == 123)
(this is actually more useful than it appears, as the decimal module
converts its numbers back and forth between ints/longs and strs all
the time)
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
@@ -312,6 +312,7 @@
# this is a weird op! we don't want to execute anything, so just record
# an operation
self.metainterp._record_helper_nonpure_varargs(rop.RECORD_KNOWN_RESULT, None, calldescr, allboxes)
+ opimpl_record_known_result_r_ir_v = opimpl_record_known_result_i_ir_v
@arguments("box", "box")
def opimpl_record_exact_value_r(self, box, const_box):
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
@@ -1075,3 +1075,33 @@
assert res == f(1)
self.check_simple_loop(int_sub=1, guard_false=1)
+ def test_int_to_str_and_back(self):
+ driver = JitDriver(greens = [], reds = ['n', 'res'])
+
+ def f(n):
+ res = 0
+ while n < 21:
+ driver.jit_merge_point(n=n, res=res)
+ n += 1
+ res += int(str(n))
+ return res
+
+ res = self.meta_interp(f, [1], backendopt=True)
+ assert res == f(1)
+ self.check_simple_loop(call_r=1, call_i=0)
+
+ def test_rbigint_to_str_and_back(self):
+ from rpython.rlib.rbigint import rbigint
+ driver = JitDriver(greens = [], reds = ['n', 'res'])
+
+ def f(n):
+ res = rbigint.fromint(0)
+ while n < 21:
+ driver.jit_merge_point(n=n, res=res)
+ n += 1
+ res = res.add(rbigint.fromstr(res.str(), 10))
+ return res.int_and_(0xffff).toint()
+
+ res = self.meta_interp(f, [1], backendopt=True)
+ assert res == f(1)
+ self.check_simple_loop(call_r=2) # one add, one str, the fromstr is gone
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -509,8 +509,13 @@
return self.format(BASE10, suffix="L")
return str(x) + "L"
+ def str(self):
+ res = self._str_impl()
+ jit.record_known_result(self, rbigint.fromstr, res, 10, False)
+ return res
+
@jit.elidable
- def str(self):
+ def _str_impl(self):
try:
x = self.toint()
except OverflowError:
diff --git a/rpython/rtyper/rint.py b/rpython/rtyper/rint.py
--- a/rpython/rtyper/rint.py
+++ b/rpython/rtyper/rint.py
@@ -146,10 +146,12 @@
hop.exception_cannot_occur()
return vlist[0]
- @jit.elidable
def ll_str(self, i):
from rpython.rtyper.lltypesystem.ll_str import ll_int2dec
- return ll_int2dec(i)
+ from rpython.rtyper.lltypesystem.rstr import LLHelpers
+ res = ll_int2dec(i)
+ jit.record_known_result(i, LLHelpers.ll_int, res, 10)
+ return res
def rtype_hex(self, hop):
from rpython.rtyper.lltypesystem.ll_str import ll_int2hex
More information about the pypy-commit
mailing list