Author: Carl Friedrich Bolz <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit