Author: Carl Friedrich Bolz <[email protected]>
Branch: guard-compatible
Changeset: r83196:07d318a03f0d
Date: 2016-03-20 15:20 +0100
http://bitbucket.org/pypy/pypy/changeset/07d318a03f0d/
Log: de-duplicate quasi-immutable conditions
diff --git a/rpython/jit/metainterp/compatible.py
b/rpython/jit/metainterp/compatible.py
--- a/rpython/jit/metainterp/compatible.py
+++ b/rpython/jit/metainterp/compatible.py
@@ -157,6 +157,8 @@
return False
if not self.res.same_constant(res):
return False
+ if self.descr is not other.descr:
+ return False
assert self.args[1] is other.args[1] is None
for i in range(len(self.args)):
if i == 1:
@@ -168,28 +170,36 @@
class QuasiimmutGetfieldAndPureCallCondition(PureCallCondition):
def __init__(self, op, qmutdescr):
- self.op = op
- self.qmutdescr = qmutdescr
+ args = op.getarglist()[:]
+ args[1] = None
+ args[2] = None
+ self.args = args
+ self.descr = op.getdescr()
+ self.qmut = qmutdescr.qmut
+ self.mutatefielddescr = qmutdescr.mutatefielddescr
+ self.fielddescr = qmutdescr.fielddescr
def activate(self, ref, optimizer):
# record the quasi-immutable
- optimizer.record_quasi_immutable_dep(self.qmutdescr.qmut)
+ optimizer.record_quasi_immutable_dep(self.qmut)
+ # XXX can set self.qmut to None here?
Condition.activate(self, ref, optimizer)
def activate_secondary(self, ref, loop_token):
from rpython.jit.metainterp.quasiimmut import get_current_qmut_instance
# need to register the loop for invalidation as well!
qmut = get_current_qmut_instance(loop_token.cpu, ref,
- self.qmutdescr.mutatefielddescr)
+ self.mutatefielddescr)
qmut.register_loop_token(loop_token.loop_token_wref)
def check(self, cpu, ref):
from rpython.rlib.debug import debug_print, debug_start, debug_stop
- calldescr = self.op.getdescr()
+ from rpython.jit.metainterp.quasiimmut import QuasiImmutDescr
+ calldescr = self.descr
# change exactly the first argument
- arglist = self.op.getarglist()
+ arglist = self.args
arglist[1] = newconst(ref)
- arglist[2] = self.qmutdescr._get_fieldvalue(ref)
+ arglist[2] = QuasiImmutDescr._get_fieldvalue(self.fielddescr, ref, cpu)
try:
res = do_call(cpu, arglist, calldescr)
except Exception:
@@ -197,7 +207,30 @@
debug_print("call to elidable_compatible function raised")
debug_stop("jit-guard-compatible")
return False
+ finally:
+ arglist[1] = arglist[2] = None
if not res.same_constant(self.res):
return False
return True
+ def same_cond(self, other, res):
+ if type(other) != QuasiimmutGetfieldAndPureCallCondition:
+ return False
+ if len(self.args) != len(other.args):
+ return False
+ if not self.res.same_constant(res):
+ return False
+ if self.descr is not other.descr:
+ return False
+ if self.fielddescr is not other.fielddescr:
+ return False
+ if self.mutatefielddescr is not other.mutatefielddescr:
+ return False
+ assert self.args[1] is other.args[1] is None
+ assert self.args[2] is other.args[2] is None
+ for i in range(len(self.args)):
+ if i == 1 or i == 2:
+ continue
+ if not self.args[i].same_constant(other.args[i]):
+ return False
+ return True
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_compatible.py
b/rpython/jit/metainterp/optimizeopt/test/test_compatible.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_compatible.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_compatible.py
@@ -150,7 +150,12 @@
guard_not_invalidated() []
i0 = getfield_gc_i(p1, descr=quasifielddescr)
i1 = call_pure_i(123, p1, i0, descr=nonwritedescr)
+ quasiimmut_field(p1, descr=quasiimmutdescr)
+ guard_not_invalidated() []
+ i3 = getfield_gc_i(p1, descr=quasifielddescr)
+ i4 = call_pure_i(123, p1, i3, descr=nonwritedescr)
escape_n(i1)
+ escape_n(i4)
jump(p1)
"""
expected = """
@@ -159,10 +164,14 @@
guard_not_invalidated() []
i0 = getfield_gc_i(p1, descr=quasifielddescr) # will be removed by the
backend
escape_n(5)
+ escape_n(5)
jump(p1)
"""
call_pure_results = {
(ConstInt(123), ConstPtr(self.quasiptr), ConstInt(-4247)):
ConstInt(5),
}
self.optimize_loop(ops, expected, call_pure_results)
-
+ descr = self.loop.operations[1].getdescr()
+ assert descr._compatibility_conditions is not None
+ assert
descr._compatibility_conditions.known_valid.same_constant(ConstPtr(self.quasiptr))
+ assert len(descr._compatibility_conditions.conditions) == 1
diff --git a/rpython/jit/metainterp/quasiimmut.py
b/rpython/jit/metainterp/quasiimmut.py
--- a/rpython/jit/metainterp/quasiimmut.py
+++ b/rpython/jit/metainterp/quasiimmut.py
@@ -129,16 +129,16 @@
def get_current_constant_fieldvalue(self):
struct = self.struct
- return self._get_fieldvalue(struct)
+ return self._get_fieldvalue(self.fielddescr, struct, self.cpu)
- def _get_fieldvalue(self, struct):
- fielddescr = self.fielddescr
- if self.fielddescr.is_pointer_field():
- return ConstPtr(self.cpu.bh_getfield_gc_r(struct, fielddescr))
- elif self.fielddescr.is_float_field():
- return ConstFloat(self.cpu.bh_getfield_gc_f(struct, fielddescr))
+ @staticmethod
+ def _get_fieldvalue(fielddescr, struct, cpu):
+ if fielddescr.is_pointer_field():
+ return ConstPtr(cpu.bh_getfield_gc_r(struct, fielddescr))
+ elif fielddescr.is_float_field():
+ return ConstFloat(cpu.bh_getfield_gc_f(struct, fielddescr))
else:
- return ConstInt(self.cpu.bh_getfield_gc_i(struct, fielddescr))
+ return ConstInt(cpu.bh_getfield_gc_i(struct, fielddescr))
def is_still_valid_for(self, structconst):
assert self.struct
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit