Author: Alex Gaynor <[email protected]>
Branch:
Changeset: r64493:f6e4e1ccc876
Date: 2013-05-22 15:49 -0700
http://bitbucket.org/pypy/pypy/changeset/f6e4e1ccc876/
Log: When ll_shrink_array is called a constant string allow that to be
propogated.
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
@@ -21,6 +21,7 @@
OS_NONE = 0 # normal case, no oopspec
OS_ARRAYCOPY = 1 # "list.ll_arraycopy"
OS_STR2UNICODE = 2 # "str.str2unicode"
+ OS_SHRINK_ARRAY = 3 # rgc.ll_shrink_array
#
OS_STR_CONCAT = 22 # "stroruni.concat"
OS_STR_SLICE = 23 # "stroruni.slice"
@@ -82,8 +83,10 @@
OS_JIT_FORCE_VIRTUAL = 120
# for debugging:
- _OS_CANRAISE = set([OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL,
- OS_RAW_MALLOC_VARSIZE_CHAR, OS_JIT_FORCE_VIRTUAL])
+ _OS_CANRAISE = set([
+ OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL, OS_RAW_MALLOC_VARSIZE_CHAR,
+ OS_JIT_FORCE_VIRTUAL, OS_SHRINK_ARRAY,
+ ])
def __new__(cls, readonly_descrs_fields, readonly_descrs_arrays,
write_descrs_fields, write_descrs_arrays,
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
@@ -398,6 +398,8 @@
prepare = self._handle_libffi_call
elif oopspec_name.startswith('math.sqrt'):
prepare = self._handle_math_sqrt_call
+ elif oopspec_name.startswith('rgc.'):
+ prepare = self._handle_rgc_call
else:
prepare = self.prepare_builtin_call
try:
@@ -1779,6 +1781,12 @@
return self._handle_oopspec_call(op, args, EffectInfo.OS_MATH_SQRT,
EffectInfo.EF_ELIDABLE_CANNOT_RAISE)
+ def _handle_rgc_call(self, op, oopspec_name, args):
+ if oopspec_name == 'rgc.ll_shrink_array':
+ return self._handle_oopspec_call(op, args,
EffectInfo.OS_SHRINK_ARRAY, EffectInfo.EF_CAN_RAISE)
+ else:
+ raise NotImplementedError(oopspec_name)
+
def rewrite_op_jit_force_quasi_immutable(self, op):
v_inst, c_fieldname = op.args
descr1 = self.cpu.fielddescrof(v_inst.concretetype.TO,
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
@@ -136,6 +136,9 @@
assert size <= MAX_CONST_LEN
self._chars = [None] * size
+ def shrink(self, length):
+ del self._chars[length:]
+
def setup_slice(self, longerlist, start, stop):
assert 0 <= start <= stop <= len(longerlist)
self._chars = longerlist[start:stop]
@@ -554,6 +557,9 @@
if oopspecindex == EffectInfo.OS_STR2UNICODE:
if self.opt_call_str_STR2UNICODE(op):
return
+ if oopspecindex == EffectInfo.OS_SHRINK_ARRAY:
+ if self.opt_call_SHRINK_ARRAY(op):
+ return
self.emit_operation(op)
optimize_CALL_PURE = optimize_CALL
@@ -721,6 +727,19 @@
return True
return False
+ def opt_call_SHRINK_ARRAY(self, op):
+ v1 = self.getvalue(op.getarg(1))
+ v2 = self.getvalue(op.getarg(2))
+ # If the index is constant, if the argument is virtual (we only support
+ # VStringPlainValue for now) we can optimize away the call.
+ if v2.is_constant() and v1.is_virtual() and isinstance(v1,
VStringPlainValue):
+ length = v2.box.getint()
+ v1.shrink(length)
+ self.last_emitted_operation = REMOVED
+ self.make_equal_to(op.result, v1)
+ return True
+ return False
+
def generate_modified_call(self, oopspecindex, args, result, mode):
oopspecindex += mode.OS_offset
cic = self.optimizer.metainterp_sd.callinfocollection
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
@@ -582,6 +582,26 @@
res = self.interp_operations(f, [13])
assert res == 13
+ def test_shrink_array(self):
+ jitdriver = JitDriver(reds=['result', 'n'], greens=[])
+ _str, _StringBuilder = self._str, self._StringBuilder
+
+ def f(n):
+ result = 0
+ while n >= 0:
+ jitdriver.jit_merge_point(n=n, result=result)
+ b = _StringBuilder(20)
+ b.append(_str("Testing!"))
+ result += len(b.build())
+ n -= 1
+ return result
+
+ res = self.meta_interp(f, [9])
+ assert res == f(9)
+ self.check_resops({
+ 'jump': 1, 'guard_true': 2, 'int_ge': 2, 'int_add': 2, 'int_sub': 2
+ })
+
#class TestOOtype(StringTests, OOJitMixin):
# CALL = "oosend"
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -183,6 +183,7 @@
return True
return False
+
@jit.oopspec('list.ll_arraycopy(source, dest, source_start, dest_start,
length)')
@enforceargs(None, None, int, int, int)
@specialize.ll()
@@ -229,6 +230,9 @@
keepalive_until_here(source)
keepalive_until_here(dest)
+
[email protected]('rgc.ll_shrink_array(p, smallerlength)')
[email protected]()
def ll_shrink_array(p, smallerlength):
from rpython.rtyper.lltypesystem.lloperation import llop
from rpython.rlib.objectmodel import keepalive_until_here
@@ -249,16 +253,15 @@
ARRAY = getattr(TP, TP._arrayfld)
offset = (llmemory.offsetof(TP, TP._arrayfld) +
llmemory.itemoffsetof(ARRAY, 0))
- source_addr = llmemory.cast_ptr_to_adr(p) + offset
- dest_addr = llmemory.cast_ptr_to_adr(newp) + offset
+ source_addr = llmemory.cast_ptr_to_adr(p) + offset
+ dest_addr = llmemory.cast_ptr_to_adr(newp) + offset
llmemory.raw_memcopy(source_addr, dest_addr,
llmemory.sizeof(ARRAY.OF) * smallerlength)
keepalive_until_here(p)
keepalive_until_here(newp)
return newp
-ll_shrink_array._annspecialcase_ = 'specialize:ll'
-ll_shrink_array._jit_look_inside_ = False
+
def no_collect(func):
func._dont_inline_ = True
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit