[pypy-commit] pypy getarrayitem-into-bridges: support for caching infos on constants, while I'm at it
cfbolz
pypy.commits at gmail.com
Wed Aug 2 13:50:56 EDT 2017
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: getarrayitem-into-bridges
Changeset: r92045:f105d8c2eae7
Date: 2017-08-02 18:04 +0200
http://bitbucket.org/pypy/pypy/changeset/f105d8c2eae7/
Log: support for caching infos on constants, while I'm at it
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -706,11 +706,11 @@
if not parent_descr.is_object():
continue # XXX could be extended to non-instance objects
for i, box1 in enumerate(cf.cached_structs):
- if box1 not in available_boxes:
+ if not box1.is_constant() and box1 not in available_boxes:
continue
structinfo = cf.cached_infos[i]
box2 = structinfo.getfield(descr).get_box_replacement()
- if isinstance(box2, Const) or box2 in available_boxes:
+ if box2.is_constant() or box2 in available_boxes:
result_getfield.append((box1, descr, box2))
result_array = []
for descr, indexdict in self.cached_arrayitems.iteritems():
@@ -718,11 +718,11 @@
if cf._lazy_set:
continue # XXX safe default for now
for i, box1 in enumerate(cf.cached_structs):
- if box1 not in available_boxes:
+ if not box1.is_constant() and box1 not in available_boxes:
continue
arrayinfo = cf.cached_infos[i]
box2 = arrayinfo.getitem(descr, index).get_box_replacement()
- if isinstance(box2, Const) or box2 in available_boxes:
+ if box2.is_constant() or box2 in available_boxes:
result_array.append((box1, index, descr, box2))
return result_getfield, result_array
@@ -730,19 +730,25 @@
for box1, descr, box2 in triples_struct:
parent_descr = descr.get_parent_descr()
assert parent_descr.is_object()
- structinfo = box1.get_forwarded()
- if not isinstance(structinfo, info.AbstractVirtualPtrInfo):
- structinfo = info.InstancePtrInfo(parent_descr)
- structinfo.init_fields(parent_descr, descr.get_index())
- box1.set_forwarded(structinfo)
+ if box1.is_constant():
+ structinfo = info.ConstPtrInfo(box1)
+ else:
+ structinfo = box1.get_forwarded()
+ if not isinstance(structinfo, info.AbstractVirtualPtrInfo):
+ structinfo = info.InstancePtrInfo(parent_descr)
+ structinfo.init_fields(parent_descr, descr.get_index())
+ box1.set_forwarded(structinfo)
cf = self.field_cache(descr)
structinfo.setfield(descr, box1, box2, optheap=self, cf=cf)
for box1, index, descr, box2 in triples_array:
- arrayinfo = box1.get_forwarded()
- if not isinstance(arrayinfo, info.AbstractVirtualPtrInfo):
- arrayinfo = info.ArrayPtrInfo(descr)
- box1.set_forwarded(arrayinfo)
+ if box1.is_constant():
+ arrayinfo = info.ConstPtrInfo(box1)
+ else:
+ arrayinfo = box1.get_forwarded()
+ if not isinstance(arrayinfo, info.AbstractVirtualPtrInfo):
+ arrayinfo = info.ArrayPtrInfo(descr)
+ box1.set_forwarded(arrayinfo)
cf = self.arrayitem_cache(descr, index)
arrayinfo.setitem(descr, index, box1, box2, optheap=self, cf=cf)
diff --git a/rpython/jit/metainterp/test/test_bridgeopt.py b/rpython/jit/metainterp/test/test_bridgeopt.py
--- a/rpython/jit/metainterp/test/test_bridgeopt.py
+++ b/rpython/jit/metainterp/test/test_bridgeopt.py
@@ -143,11 +143,7 @@
def test_bridge_field_read(self):
myjitdriver = jit.JitDriver(greens=[], reds=['y', 'res', 'n', 'a'])
class A(object):
- def f(self):
- return 1
- class B(A):
- def f(self):
- return 2
+ pass
class M(object):
_immutable_fields_ = ['x']
def __init__(self, x):
@@ -156,18 +152,59 @@
m1 = M(1)
m2 = M(2)
def f(x, y, n):
+ a = A()
+ a.n = n
if x:
- a = A()
+ a.m = m1
+ else:
+ a.m = m2
+ a.x = 0
+ res = 0
+ while y > 0:
+ myjitdriver.jit_merge_point(y=y, n=n, res=res, a=a)
+ n1 = a.n
+ m = jit.promote(a.m)
+ res += m.x
+ a.x += 1
+ if y > n:
+ res += 1
+ m = jit.promote(a.m)
+ res += m.x
+ res += n1 + a.n
+ y -= 1
+ return res
+ res = self.meta_interp(f, [6, 32, 16])
+ assert res == f(6, 32, 16)
+ self.check_trace_count(3)
+ self.check_resops(guard_value=1)
+ self.check_resops(getfield_gc_i=4) # 3x a.x, 1x a.n
+ self.check_resops(getfield_gc_r=1) # in main loop
+
+ def test_bridge_field_read_constants(self):
+ myjitdriver = jit.JitDriver(greens=[], reds=['y', 'res', 'n'])
+ class A(object):
+ pass
+ class M(object):
+ _immutable_fields_ = ['x']
+ def __init__(self, x):
+ self.x = x
+
+ m1 = M(1)
+ m2 = M(2)
+ a = A()
+ a.m = m1
+ a.n = 0
+ def f(x, y, n):
+ if x:
a.m = m1
a.n = n
else:
- a = B()
a.m = m2
a.n = n
a.x = 0
res = 0
while y > 0:
- myjitdriver.jit_merge_point(y=y, n=n, res=res, a=a)
+ myjitdriver.jit_merge_point(y=y, n=n, res=res)
n1 = a.n
m = jit.promote(a.m)
res += m.x
@@ -213,3 +250,35 @@
self.check_resops(guard_value=1)
self.check_resops(getarrayitem_gc_i=4)
+ def test_bridge_array_read_constant(self):
+ myjitdriver = jit.JitDriver(greens=[], reds=['y', 'res', 'n'])
+ class A(object):
+ pass
+ a = A()
+ a.l = [1, -65, 0]
+ def f(x, y, n):
+ if x:
+ a.l[0] = 1
+ else:
+ a.l[0] = 2
+ a.l[1] = n
+ a.l[2] = 0
+ res = 0
+ while y > 0:
+ myjitdriver.jit_merge_point(y=y, n=n, res=res)
+ n1 = a.l[1]
+ m = jit.promote(a.l[0])
+ res += m
+ a.l[2] += 1
+ if y > n:
+ res += 1
+ m = jit.promote(a.l[0])
+ res += m
+ res += n1 + a.l[1]
+ y -= 1
+ return res
+ res = self.meta_interp(f, [6, 32, 16])
+ assert res == f(6, 32, 16)
+ self.check_trace_count(3)
+ self.check_resops(guard_value=1)
+ self.check_resops(getarrayitem_gc_i=5)
More information about the pypy-commit
mailing list