Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: guard-compatible Changeset: r85358:9f336d3981bb Date: 2016-06-23 11:41 +0200 http://bitbucket.org/pypy/pypy/changeset/9f336d3981bb/
Log: intermediate checkin: start sketching guard_compatible support in virtualstate 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 @@ -42,12 +42,17 @@ res.frozen = True return res - def record_condition(self, cond, res, optimizer): + def contains_condition(self, cond, res=None): for oldcond in self.conditions: if oldcond.same_cond(cond, res): return True + return False + + def record_condition(self, cond, res, optimizer): + if self.contains_condition(cond, res): + return True if self.frozen: - False + return False cond.activate(res, optimizer) if self.conditions and self.conditions[-1].debug_mp_str == cond.debug_mp_str: cond.debug_mp_str = '' @@ -57,11 +62,17 @@ def register_quasi_immut_field(self, op): self.last_quasi_immut_field_op = op - def check_compat_and_activate(self, cpu, ref, loop_token): + def check_compat(self, cpu, ref): for cond in self.conditions: if not cond.check(cpu, ref): return False - # need to tell all conditions, in case a quasi-immut needs to be registered + return True + + def check_compat_and_activate(self, cpu, ref, loop_token): + if not self.check_compat(cpu, ref): + return False + # need to tell all conditions, in case a quasi-immut needs to be + # registered for cond in self.conditions: cond.activate_secondary(ref, loop_token) return True @@ -123,6 +134,23 @@ for cond in self.conditions: cond.emit_condition(op, short, optimizer) + def emit_needed_conditions_if_const_matches( + self, other, const, op, extra_guards, optimizer, cpu): + """ go through self.conditions. if the condition is present in other, + do nothing. If it is not, check whether ref matches the condition. If + not return False, otherwise emit guards for the condition. Return True + at the end. """ + for cond in self.conditions: + if other is None or not other.contains_condition(cond): + if const is None: + return False + ref = const.getref_base() + if cond.check(cpu, ref): + cond.emit_condition(op, short, optimizer) + else: + return False + return True + def repr_of_conditions(self, argrepr="?"): return "\n".join([cond.repr(argrepr) for cond in self.conditions]) @@ -151,7 +179,7 @@ def activate_secondary(self, ref, loop_token): pass - def same_cond(self, other, res): + def same_cond(self, other, res=None): return False def repr(self): @@ -216,11 +244,13 @@ return False return True - def same_cond(self, other, res): + def same_cond(self, other, res=None): if type(other) is not PureCallCondition: return False if len(self.args) != len(other.args): return False + if res is None: + res = other.res if not self.res.same_constant(res): return False if self.descr is not other.descr: @@ -321,11 +351,13 @@ return False return True - def same_cond(self, other, res): + def same_cond(self, other, res=None): if type(other) is not QuasiimmutGetfieldAndPureCallCondition: return False if len(self.args) != len(other.args): return False + if res is None: + res = other.res if not self.res.same_constant(res): return False if self.descr is not other.descr: diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py b/rpython/jit/metainterp/optimizeopt/virtualstate.py --- a/rpython/jit/metainterp/optimizeopt/virtualstate.py +++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py @@ -355,6 +355,8 @@ if type == 'i': return NotVirtualStateInfoInt(cpu, type, info) if type == 'r': + if info._compatibility_conditions is not None: + return NotVirtualStateInfoPtrCompatible(cpu, type, info) return NotVirtualStateInfoPtr(cpu, type, info) return NotVirtualStateInfo(cpu, type, info) @@ -597,6 +599,29 @@ else: raise VirtualStatesCantMatch("classes don't match") +class NotVirtualStateInfoPtrCompatible(NotVirtualStateInfoPtr): + def __init__(self, cpu, type, info): + ccond = info._compatibility_conditions + self._compatibility_conditions = ccond.frozen_copy() + NotVirtualStateInfoPtr.__init__(self, cpu, type, info) + + def _generate_guards(self, other, box, runtime_box, state): + NotVirtualStateInfoPtr._generate_guards( + self, other, box, runtime_box, state) + ccond_self = self._compatibility_conditions + if isinstance(other, NotVirtualStateInfoPtrCompatible): + ccond_other = other._compatibility_conditions + else: + ccond_other = None + const = None + if runtime_box is not None: + const = runtime_box.constbox() + if ccond_self.emit_needed_conditions_if_const_matches( + ccond_other, const, box, state.extra_guards, + state.optimizer, state.cpu): + return + raise VirtualStatesCantMatch("target compatibility conditions aren't met") + class VirtualState(object): def __init__(self, state): diff --git a/rpython/jit/metainterp/test/test_compatible.py b/rpython/jit/metainterp/test/test_compatible.py --- a/rpython/jit/metainterp/test/test_compatible.py +++ b/rpython/jit/metainterp/test/test_compatible.py @@ -42,8 +42,8 @@ x = self.meta_interp(main, []) assert x < 30 - # trace, two bridges, a finish bridge - self.check_trace_count(4) + # trace, one bridge, a finish bridge + self.check_trace_count(3) def test_simple_check_values(self): S = lltype.GcStruct('S', ('x', lltype.Signed)) @@ -87,8 +87,8 @@ x = self.meta_interp(main, []) assert x == main() - # trace, two bridges, a finish bridge - self.check_trace_count(4) + # trace, a bridge, a finish bridge + self.check_trace_count(3) def test_exception(self): S = lltype.GcStruct('S', ('x', lltype.Signed)) @@ -122,7 +122,7 @@ f(100, p3) self.meta_interp(main, []) - # XXX check number of bridges + self.check_trace_count(3) def test_quasi_immutable(self): @@ -197,7 +197,7 @@ x = self.meta_interp(main, [False]) assert x < 30 - # XXX check number of bridges + self.check_trace_count(4) def test_dont_record_repeated_guard_compatible(self): @@ -264,8 +264,8 @@ x = self.meta_interp(main, []) assert x < 30 - # trace, two bridges, a finish bridge - self.check_trace_count(4) + # trace, one bridge, a finish bridge + self.check_trace_count(3) def test_order_of_chained_guards(self): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit