[pypy-commit] pypy kill-gen-store-back-in: Implement a hint to call gen_store_back by hand. useful for generators
fijal
noreply at buildbot.pypy.org
Thu Jun 27 17:53:18 CEST 2013
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: kill-gen-store-back-in
Changeset: r65040:8001b03cceff
Date: 2013-06-27 17:52 +0200
http://bitbucket.org/pypy/pypy/changeset/8001b03cceff/
Log: Implement a hint to call gen_store_back by hand. useful for
generators
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
@@ -521,6 +521,8 @@
op1 = SpaceOperation('str_guard_value', [op.args[0], c, descr],
op.result)
return [SpaceOperation('-live-', [], None), op1, None]
+ if hints.get('force_virtualizable'):
+ return SpaceOperation('hint_force_virtualizable', [op.args[0]], None)
else:
log.WARNING('ignoring hint %r at %r' % (hints, self.graph))
diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -1306,6 +1306,10 @@
def bhimpl_force_virtualizable(cpu, v, descr):
cpu.bh_force_virtualizable(v, descr)
+ @arguments("r")
+ def bhimpl_hint_force_virtualizable(r):
+ pass
+
@arguments("cpu", "d", returns="r")
def bhimpl_new(cpu, descr):
return cpu.bh_new(descr)
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
@@ -674,6 +674,10 @@
opimpl_raw_load_i = _opimpl_raw_load
opimpl_raw_load_f = _opimpl_raw_load
+ @arguments("box")
+ def opimpl_hint_force_virtualizable(self, box):
+ self.metainterp.gen_store_back_in_vable(box)
+
@arguments("box", "descr", "descr", "orgpc")
def opimpl_record_quasiimmut_field(self, box, fielddescr,
mutatefielddescr, orgpc):
@@ -2509,6 +2513,33 @@
virtualizable)
self.virtualizable_boxes.append(virtualizable_box)
+ vinfo = self.jitdriver_sd.virtualizable_info
+
+ def gen_store_back_in_vable(self, box):
+ vinfo = self.jitdriver_sd.virtualizable_info
+ if vinfo is not None:
+ # xxx only write back the fields really modified
+ vbox = self.virtualizable_boxes[-1]
+ if vbox is not box:
+ return # ignore the hint on non-standard virtualizable
+ for i in range(vinfo.num_static_extra_boxes):
+ fieldbox = self.virtualizable_boxes[i]
+ descr = vinfo.static_field_descrs[i]
+ self.execute_and_record(rop.SETFIELD_GC, descr, vbox, fieldbox)
+ i = vinfo.num_static_extra_boxes
+ virtualizable = vinfo.unwrap_virtualizable_box(vbox)
+ for k in range(vinfo.num_arrays):
+ descr = vinfo.array_field_descrs[k]
+ abox = self.execute_and_record(rop.GETFIELD_GC, descr, vbox)
+ descr = vinfo.array_descrs[k]
+ for j in range(vinfo.get_array_length(virtualizable, k)):
+ itembox = self.virtualizable_boxes[i]
+ i += 1
+ self.execute_and_record(rop.SETARRAYITEM_GC, descr,
+ abox, ConstInt(j), itembox)
+ assert i + 1 == len(self.virtualizable_boxes)
+
+
def replace_box(self, oldbox, newbox):
assert isinstance(oldbox, Box)
for frame in self.framestack:
diff --git a/rpython/jit/metainterp/test/test_virtualizable.py b/rpython/jit/metainterp/test/test_virtualizable.py
--- a/rpython/jit/metainterp/test/test_virtualizable.py
+++ b/rpython/jit/metainterp/test/test_virtualizable.py
@@ -3,8 +3,9 @@
from rpython.jit.codewriter import heaptracker
from rpython.jit.codewriter.policy import StopAtXPolicy
from rpython.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin
-from rpython.jit.metainterp.test.support import LLJitMixin, OOJitMixin
-from rpython.jit.metainterp.warmspot import get_translator
+from rpython.jit.metainterp.test.support import LLJitMixin
+from rpython.jit.metainterp.warmspot import get_translator, get_stats
+from rpython.jit.metainterp.resoperation import rop
from rpython.rlib.jit import JitDriver, hint, dont_look_inside, promote, virtual_ref
from rpython.rlib.rarithmetic import intmask
from rpython.rtyper.annlowlevel import hlstr
@@ -26,7 +27,6 @@
return lltype_to_annotation(lltype.Void)
def specialize_call(self, hop):
- op = self.instance # the LLOp object that was called
args_v = [hop.inputarg(hop.args_r[0], 0),
hop.inputconst(lltype.Void, hop.args_v[1].value),
hop.inputconst(lltype.Void, {})]
@@ -1544,6 +1544,39 @@
res = self.meta_interp(f, [])
assert res == f()
+ def test_force_virtualizable_by_hint(self):
+ class Frame(object):
+ _virtualizable_ = ['x']
+
+ driver = JitDriver(greens = [], reds = ['i', 'frame'],
+ virtualizables = ['frame'])
+
+ def f(frame, i):
+ while i > 0:
+ driver.jit_merge_point(i=i, frame=frame)
+ i -= 1
+ frame.x += 1
+ hint(frame, force_virtualizable=True)
+
+ def main():
+ frame = Frame()
+ frame.x = 0
+ s = 0
+ for i in range(20):
+ f(frame, 4)
+ s += frame.x
+ return s
+
+ r = self.meta_interp(main, [])
+ assert r == main()
+ # fish the bridge
+ loop = get_stats().get_all_loops()[0]
+ d = loop.operations[-3].getdescr()
+ bridge = getattr(d, '_llgraph_bridge', None)
+ if bridge is not None:
+ l = [op for op in
+ bridge.operations if op.getopnum() == rop.SETFIELD_GC]
+ assert len(l) == 2
class TestLLtype(ExplicitVirtualizableTests,
ImplicitVirtualizableTests,
More information about the pypy-commit
mailing list