[prev in list] [next in list] [prev in thread] [next in thread]
List: pypy-svn
Subject: [pypy-commit] pypy default: merge foldable-getarrayitem-indexerror: constant-fold reads out of const
From: cfbolz <noreply () buildbot ! pypy ! org>
Date: 2013-07-31 10:18:52
Message-ID: 20130731101852.9A4F31C02E4 () cobra ! cs ! uni-duesseldorf ! de
[Download RAW message or body]
Author: Carl Friedrich Bolz <cfbolz@gmx.de>
Branch:
Changeset: r65858:27316dbf2693
Date: 2013-07-31 12:18 +0200
http://bitbucket.org/pypy/pypy/changeset/27316dbf2693/
Log: merge foldable-getarrayitem-indexerror: constant-fold reads out of
constant applevel tuples
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -54,3 +54,7 @@
speeds up list.append() and list.pop().
.. branch: curses_fixes
+
+.. branch: foldable-getarrayitem-indexerror
+Constant-fold reading out of constant tuples in PyPy.
+
diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py \
b/pypy/module/pypyjit/test_pypy_c/test_containers.py
--- a/pypy/module/pypyjit/test_pypy_c/test_containers.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py
@@ -209,6 +209,22 @@
opnames = log.opnames(loop.allops())
assert opnames.count('new_with_vtable') == 0
+ def test_constfold_tuple(self):
+ code = """if 1:
+ tup = tuple(range(10000))
+ l = [1, 2, 3, 4, 5, 6, "a"]
+ def main(n):
+ while n > 0:
+ sub = tup[1] # ID: getitem
+ l[1] = n # kill cache of tup[1]
+ n -= sub
+ """
+ log = self.run(code, [1000])
+ loop, = log.loops_by_filename(self.filepath)
+ ops = loop.ops_by_id('getitem', include_guard_not_invalidated=False)
+ assert log.opnames(ops) == []
+
+
def test_specialised_tuple(self):
def main(n):
import pypyjit
diff --git a/rpython/jit/metainterp/test/test_immutable.py \
b/rpython/jit/metainterp/test/test_immutable.py
--- a/rpython/jit/metainterp/test/test_immutable.py
+++ b/rpython/jit/metainterp/test/test_immutable.py
@@ -69,6 +69,28 @@
self.check_operations_history(getfield_gc=0, getfield_gc_pure=1,
getarrayitem_gc=0, getarrayitem_gc_pure=1)
+ def test_array_index_error(self):
+ class X(object):
+ _immutable_fields_ = ["y[*]"]
+
+ def __init__(self, x):
+ self.y = x
+
+ def get(self, index):
+ try:
+ return self.y[index]
+ except IndexError:
+ return -41
+
+ def f(index):
+ l = [1, 2, 3, 4]
+ l[2] = 30
+ a = escape(X(l))
+ return a.get(index)
+ res = self.interp_operations(f, [2], listops=True)
+ assert res == 30
+ self.check_operations_history(getfield_gc=0, getfield_gc_pure=1,
+ getarrayitem_gc=0, getarrayitem_gc_pure=1)
def test_array_in_immutable(self):
class X(object):
diff --git a/rpython/rtyper/rlist.py b/rpython/rtyper/rlist.py
--- a/rpython/rtyper/rlist.py
+++ b/rpython/rtyper/rlist.py
@@ -247,27 +247,22 @@
v_lst, v_index = hop.inputargs(r_lst, Signed)
if checkidx:
hop.exception_is_here()
+ spec = dum_checkidx
else:
+ spec = dum_nocheck
hop.exception_cannot_occur()
- if hop.args_s[0].listdef.listitem.mutated or checkidx:
- if hop.args_s[1].nonneg:
- llfn = ll_getitem_nonneg
- else:
- llfn = ll_getitem
- if checkidx:
- spec = dum_checkidx
- else:
- spec = dum_nocheck
- c_func_marker = hop.inputconst(Void, spec)
- v_res = hop.gendirectcall(llfn, c_func_marker, v_lst, v_index)
+ if hop.args_s[0].listdef.listitem.mutated:
+ basegetitem = ll_getitem_fast
else:
- # this is the 'foldable' version, which is not used when
- # we check for IndexError
- if hop.args_s[1].nonneg:
- llfn = ll_getitem_foldable_nonneg
- else:
- llfn = ll_getitem_foldable
- v_res = hop.gendirectcall(llfn, v_lst, v_index)
+ basegetitem = ll_getitem_foldable_nonneg
+
+ if hop.args_s[1].nonneg:
+ llfn = ll_getitem_nonneg
+ else:
+ llfn = ll_getitem
+ c_func_marker = hop.inputconst(Void, spec)
+ c_basegetitem = hop.inputconst(Void, basegetitem)
+ v_res = hop.gendirectcall(llfn, c_func_marker, c_basegetitem, v_lst, \
v_index) return r_lst.recast(hop.llops, v_res)
rtype_getitem_key = rtype_getitem
@@ -654,16 +649,16 @@
i += 1
length_1_i -= 1
-def ll_getitem_nonneg(func, l, index):
+def ll_getitem_nonneg(func, basegetitem, l, index):
ll_assert(index >= 0, "unexpectedly negative list getitem index")
if func is dum_checkidx:
if index >= l.ll_length():
raise IndexError
- return l.ll_getitem_fast(index)
+ return basegetitem(l, index)
ll_getitem_nonneg._always_inline_ = True
# no oopspec -- the function is inlined by the JIT
-def ll_getitem(func, l, index):
+def ll_getitem(func, basegetitem, l, index):
if func is dum_checkidx:
length = l.ll_length() # common case: 0 <= index < length
if r_uint(index) >= r_uint(length):
@@ -680,21 +675,18 @@
if index < 0:
index += l.ll_length()
ll_assert(index >= 0, "negative list getitem index out of bound")
+ return basegetitem(l, index)
+# no oopspec -- the function is inlined by the JIT
+
+def ll_getitem_fast(l, index):
return l.ll_getitem_fast(index)
-# no oopspec -- the function is inlined by the JIT
+ll_getitem_fast._always_inline_ = True
def ll_getitem_foldable_nonneg(l, index):
ll_assert(index >= 0, "unexpectedly negative list getitem index")
return l.ll_getitem_fast(index)
ll_getitem_foldable_nonneg.oopspec = 'list.getitem_foldable(l, index)'
-def ll_getitem_foldable(l, index):
- if index < 0:
- index += l.ll_length()
- return ll_getitem_foldable_nonneg(l, index)
-ll_getitem_foldable._always_inline_ = True
-# no oopspec -- the function is inlined by the JIT
-
def ll_setitem_nonneg(func, l, index, newitem):
ll_assert(index >= 0, "unexpectedly negative list setitem index")
if func is dum_checkidx:
diff --git a/rpython/rtyper/test/test_rlist.py b/rpython/rtyper/test/test_rlist.py
--- a/rpython/rtyper/test/test_rlist.py
+++ b/rpython/rtyper/test/test_rlist.py
@@ -14,15 +14,19 @@
from rpython.translator.translator import TranslationContext
-# undo the specialization parameter
+# undo the specialization parameters
for n1 in 'get set del'.split():
+ if n1 == "get":
+ extraarg = "ll_getitem_fast, "
+ else:
+ extraarg = ""
for n2 in '', '_nonneg':
name = 'll_%sitem%s' % (n1, n2)
globals()['_' + name] = globals()[name]
exec """if 1:
def %s(*args):
- return _%s(dum_checkidx, *args)
-""" % (name, name)
+ return _%s(dum_checkidx, %s*args)
+""" % (name, name, extraarg)
del n1, n2, name
@@ -1400,7 +1404,7 @@
block = graph.startblock
op = block.operations[-1]
assert op.opname == 'direct_call'
- func = op.args[0].value._obj._callable
+ func = op.args[2].value
assert ('foldable' in func.func_name) == \
("y[*]" in immutable_fields)
@@ -1511,8 +1515,8 @@
block = graph.startblock
lst1_getitem_op = block.operations[-3] # XXX graph fishing
lst2_getitem_op = block.operations[-2]
- func1 = lst1_getitem_op.args[0].value._obj._callable
- func2 = lst2_getitem_op.args[0].value._obj._callable
+ func1 = lst1_getitem_op.args[2].value
+ func2 = lst2_getitem_op.args[2].value
assert func1.oopspec == 'list.getitem_foldable(l, index)'
assert not hasattr(func2, 'oopspec')
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic