Author: Carl Friedrich Bolz <[email protected]>
Branch:
Changeset: r73830:63f7e728d745
Date: 2014-10-06 23:17 +0200
http://bitbucket.org/pypy/pypy/changeset/63f7e728d745/
Log: optimize quasi-immutable fields during tracing
this reduces the warmup. still missing to do the same thing for
quasi-immutable arrays.
the commit removes the previous support for changing the quasi-
immutable field during tracing (which was rather obscure anyway)
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
@@ -785,6 +785,8 @@
raise Exception("getfield_raw_r (without _pure) not supported")
#
if immut in (IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY):
+ if immut is IR_QUASIIMMUTABLE:
+ op1.opname += "_pure"
descr1 = self.cpu.fielddescrof(
v_inst.concretetype.TO,
quasiimmut.get_mutate_field_name(c_fieldname.value))
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
@@ -6,6 +6,7 @@
from rpython.jit.metainterp.jitexc import JitException
from rpython.jit.metainterp.optimizeopt.optimizer import Optimization,
MODE_ARRAY, LEVEL_KNOWNCLASS, REMOVED
from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
+from rpython.jit.metainterp.optimize import InvalidLoop
from rpython.jit.metainterp.resoperation import rop, ResOperation
from rpython.rlib.objectmodel import we_are_translated
@@ -544,12 +545,10 @@
qmutdescr = op.getdescr()
assert isinstance(qmutdescr, QuasiImmutDescr)
# check that the value is still correct; it could have changed
- # already between the tracing and now. In this case, we are
- # simply ignoring the QUASIIMMUT_FIELD hint and compiling it
- # as a regular getfield.
+ # already between the tracing and now. In this case, we mark the loop
+ # as invalid
if not qmutdescr.is_still_valid_for(structvalue.get_key_box()):
- self._remove_guard_not_invalidated = True
- return
+ raise InvalidLoop('quasi immutable field changed during tracing')
# record as an out-of-line guard
if self.optimizer.quasi_immutable_deps is None:
self.optimizer.quasi_immutable_deps = {}
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -8253,13 +8253,7 @@
setfield_gc(p106, p108, descr=nextdescr) # inst_storage
jump(p106)
"""
- expected = """
- []
- p72 = getfield_gc(ConstPtr(myptr2), descr=quasifielddescr)
- guard_value(p72, -4247) []
- jump()
- """
- self.optimize_loop(ops, expected)
+ self.raises(InvalidLoop, self.optimize_loop, ops, ops)
def test_issue1080_infinitie_loop_simple(self):
ops = """
@@ -8270,13 +8264,7 @@
guard_value(p71, -4247) []
jump(ConstPtr(myptr))
"""
- expected = """
- []
- p72 = getfield_gc(ConstPtr(myptr), descr=quasifielddescr)
- guard_value(p72, -4247) []
- jump()
- """
- self.optimize_loop(ops, expected)
+ self.raises(InvalidLoop, self.optimize_loop, ops, ops)
def test_only_strengthen_guard_if_class_matches(self):
ops = """
diff --git a/rpython/jit/metainterp/test/test_quasiimmut.py
b/rpython/jit/metainterp/test/test_quasiimmut.py
--- a/rpython/jit/metainterp/test/test_quasiimmut.py
+++ b/rpython/jit/metainterp/test/test_quasiimmut.py
@@ -81,6 +81,27 @@
assert len(loop.quasi_immutable_deps) == 1
assert isinstance(loop.quasi_immutable_deps.keys()[0], QuasiImmut)
+ def test_simple_optimize_during_tracing(self):
+ myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
+ class Foo:
+ _immutable_fields_ = ['a?']
+ def __init__(self, a):
+ self.a = a
+ def f(a, x):
+ foo = Foo(a)
+ total = 0
+ while x > 0:
+ myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
+ # read a quasi-immutable field out of a Constant
+ total += foo.a
+ x -= 1
+ return total
+ #
+ res = self.meta_interp(f, [100, 7], enable_opts="")
+ assert res == 700
+ # there should be no getfields, even though optimizations are turned
off
+ self.check_resops(guard_not_invalidated=1, getfield_gc=0)
+
def test_nonopt_1(self):
myjitdriver = JitDriver(greens=[], reds=['x', 'total', 'lst'])
class Foo:
@@ -102,7 +123,7 @@
assert f(100, 7) == 721
res = self.meta_interp(f, [100, 7])
assert res == 721
- self.check_resops(guard_not_invalidated=0, getfield_gc=3)
+ self.check_resops(guard_not_invalidated=0, getfield_gc=1,
getfield_gc_pure=2)
#
from rpython.jit.metainterp.warmspot import get_stats
loops = get_stats().loops
@@ -154,11 +175,12 @@
residual_call(foo)
x -= 1
return total
- #
+
assert f(100, 7) == 721
res = self.meta_interp(f, [100, 7])
assert res == 721
- self.check_resops(guard_not_invalidated=0, getfield_gc=2)
+ # the loop is invalid, so nothing is traced
+ self.check_aborted_count(2)
def test_change_during_tracing_2(self):
myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
@@ -184,7 +206,7 @@
assert f(100, 7) == 700
res = self.meta_interp(f, [100, 7])
assert res == 700
- self.check_resops(guard_not_invalidated=0, getfield_gc=2)
+ self.check_resops(guard_not_invalidated=0, getfield_gc=0)
def test_change_invalidate_reentering(self):
myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit