Author: Carl Friedrich Bolz <[email protected]>
Branch:
Changeset: r85246:42550fb84ea8
Date: 2016-06-20 15:41 +0200
http://bitbucket.org/pypy/pypy/changeset/42550fb84ea8/
Log: move a lot of code into NotVirtualStateInfoPtr, that was so far
applied to ints and floats as well
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
@@ -260,9 +260,10 @@
self.check_no_guards(unknown_info, knownclass_info)
# unknown constant
- self.check_no_guards(unknown_info, constant_info,
+ unknown_info_int = not_virtual(self.cpu, 'i', None)
+ self.check_no_guards(unknown_info_int, constant_info,
ConstInt(1), ConstIntBound(1))
- self.check_no_guards(unknown_info, constant_info)
+ self.check_no_guards(unknown_info_int, constant_info)
# nonnull unknown
@@ -293,11 +294,11 @@
const_nonnull = ConstPtr(self.nodeaddr)
const_nonnull2 = ConstPtr(self.node2addr)
const_null = ConstPtr(lltype.nullptr(llmemory.GCREF.TO))
- self.check_no_guards(nonnull_info, constant_info, const_nonnull,
+ self.check_no_guards(nonnull_info, constant_ptr_info, const_nonnull,
info.ConstPtrInfo(const_nonnull))
self.check_invalid(nonnull_info, constantnull_info, const_null,
info.ConstPtrInfo(const_null))
- self.check_no_guards(nonnull_info, constant_info)
+ self.check_no_guards(nonnull_info, constant_ptr_info)
self.check_invalid(nonnull_info, constantnull_info)
@@ -706,7 +707,7 @@
assert not vstate2.generalization_of(vstate1, FakeOptimizer(self.cpu))
assert not vstate1.generalization_of(vstate2, FakeOptimizer(self.cpu))
-
+
def test_nonvirtual_is_not_virtual(self):
info1 = VirtualStateInfo(ConstInt(42), [1, 2])
classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr))
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
@@ -354,33 +354,19 @@
def not_virtual(cpu, type, info):
if type == 'i':
return NotVirtualStateInfoInt(cpu, type, info)
+ if type == 'r':
+ return NotVirtualStateInfoPtr(cpu, type, info)
return NotVirtualStateInfo(cpu, type, info)
class NotVirtualStateInfo(AbstractVirtualStateInfo):
- lenbound = None
level = LEVEL_UNKNOWN
constbox = None
- known_class = None
def __init__(self, cpu, type, info):
if info and info.is_constant():
self.level = LEVEL_CONSTANT
self.constbox = info.getconst()
- if type == 'r':
- self.known_class = info.get_known_class(cpu)
- elif type == 'r':
- if info:
- self.known_class = info.get_known_class(cpu)
- if self.known_class:
- self.level = LEVEL_KNOWNCLASS
- elif info.is_nonnull():
- self.level = LEVEL_NONNULL
- self.lenbound = info.getlenbound(None)
- elif type == 'f':
- if info and info.is_constant():
- self.level = LEVEL_CONSTANT
- self.constbox = info.getconst()
def is_const(self):
return self.constbox is not None
@@ -391,82 +377,15 @@
def _generate_guards(self, other, box, runtime_box, state):
# XXX This will always retrace instead of forcing anything which
# might be what we want sometimes?
- if not isinstance(other, NotVirtualStateInfo):
- raise VirtualStatesCantMatch(
- 'The VirtualStates does not match as a ' +
- 'virtual appears where a pointer is needed ' +
- 'and it is too late to force it.')
-
-
extra_guards = state.extra_guards
- cpu = state.cpu
- if self.lenbound:
- if other.lenbound is None:
- other_bound = IntLowerBound(0)
- else:
- other_bound = other.lenbound
- if not self.lenbound.contains_bound(other_bound):
- raise VirtualStatesCantMatch("length bound does not match")
-
if self.level == LEVEL_UNKNOWN:
return self._generate_guards_unkown(other, box, runtime_box,
extra_guards,
- state.optimizer)
-
- # the following conditions often peek into the runtime value that the
- # box had when tracing. This value is only used as an educated guess.
- # It is used here to choose between either emitting a guard and jumping
- # to an existing compiled loop or retracing the loop. Both alternatives
- # will always generate correct behaviour, but performance will differ.
- elif self.level == LEVEL_NONNULL:
- if other.level == LEVEL_UNKNOWN:
- if runtime_box is not None and runtime_box.nonnull():
- op = ResOperation(rop.GUARD_NONNULL, [box])
- extra_guards.append(op)
- return
- else:
- raise VirtualStatesCantMatch("other not known to be
nonnull")
- elif other.level == LEVEL_NONNULL:
- return
- elif other.level == LEVEL_KNOWNCLASS:
- return # implies nonnull
- else:
- assert other.level == LEVEL_CONSTANT
- assert other.constbox
- if not other.constbox.nonnull():
- raise VirtualStatesCantMatch("constant is null")
- return
-
- elif self.level == LEVEL_KNOWNCLASS:
- if other.level == LEVEL_UNKNOWN:
- if (runtime_box and runtime_box.nonnull() and
- self.known_class.same_constant(cpu.ts.cls_of_box(runtime_box))):
- op = ResOperation(rop.GUARD_NONNULL_CLASS, [box,
self.known_class])
- extra_guards.append(op)
- return
- else:
- raise VirtualStatesCantMatch("other's class is unknown")
- elif other.level == LEVEL_NONNULL:
- if (runtime_box and self.known_class.same_constant(
- cpu.ts.cls_of_box(runtime_box))):
- op = ResOperation(rop.GUARD_CLASS, [box, self.known_class])
- extra_guards.append(op)
- return
- else:
- raise VirtualStatesCantMatch("other's class is unknown")
- elif other.level == LEVEL_KNOWNCLASS:
- if self.known_class.same_constant(other.known_class):
- return
- raise VirtualStatesCantMatch("classes don't match")
- else:
- assert other.level == LEVEL_CONSTANT
- if (other.constbox.nonnull() and
-
self.known_class.same_constant(cpu.ts.cls_of_box(other.constbox))):
- return
- else:
- raise VirtualStatesCantMatch("classes don't match")
-
+ state)
else:
+ if not isinstance(other, NotVirtualStateInfo):
+ raise VirtualStatesCantMatch(
+ 'comparing a constant against something that is a
virtual')
assert self.level == LEVEL_CONSTANT
if other.level == LEVEL_CONSTANT:
if self.constbox.same_constant(other.constbox):
@@ -481,7 +400,7 @@
assert 0, "unreachable"
def _generate_guards_unkown(self, other, box, runtime_box, extra_guards,
- optimizer):
+ state):
return
def enum_forced_boxes(self, boxes, box, optimizer, force_boxes=False):
@@ -579,6 +498,105 @@
return self.intbound.__repr__()
+class NotVirtualStateInfoPtr(NotVirtualStateInfo):
+ lenbound = None
+ known_class = None
+
+ def __init__(self, cpu, type, info):
+ if info:
+ self.known_class = info.get_known_class(cpu)
+ if self.known_class:
+ self.level = LEVEL_KNOWNCLASS
+ elif info.is_nonnull():
+ self.level = LEVEL_NONNULL
+ self.lenbound = info.getlenbound(None)
+ # might set it to LEVEL_CONSTANT
+ NotVirtualStateInfo.__init__(self, cpu, type, info)
+
+ def _generate_guards(self, other, box, runtime_box, state):
+ if not isinstance(other, NotVirtualStateInfoPtr):
+ raise VirtualStatesCantMatch(
+ 'The VirtualStates does not match as a ' +
+ 'virtual appears where a pointer is needed ' +
+ 'and it is too late to force it.')
+ extra_guards = state.extra_guards
+ if self.lenbound:
+ if other.lenbound is None:
+ other_bound = IntLowerBound(0)
+ else:
+ other_bound = other.lenbound
+ if not self.lenbound.contains_bound(other_bound):
+ raise VirtualStatesCantMatch("length bound does not match")
+ if self.level == LEVEL_NONNULL:
+ return self._generate_guards_nonnull(other, box, runtime_box,
+ extra_guards,
+ state)
+ elif self.level == LEVEL_KNOWNCLASS:
+ return self._generate_guards_knownclass(other, box, runtime_box,
+ extra_guards,
+ state)
+ return NotVirtualStateInfo._generate_guards(self, other, box,
+ runtime_box, state)
+
+
+ # the following methods often peek into the runtime value that the
+ # box had when tracing. This value is only used as an educated guess.
+ # It is used here to choose between either emitting a guard and jumping
+ # to an existing compiled loop or retracing the loop. Both alternatives
+ # will always generate correct behaviour, but performance will differ.
+
+ def _generate_guards_nonnull(self, other, box, runtime_box, extra_guards,
+ state):
+ if not isinstance(other, NotVirtualStateInfoPtr):
+ raise VirtualStatesCantMatch('trying to match ptr with non-ptr??!')
+ if other.level == LEVEL_UNKNOWN:
+ if runtime_box is not None and runtime_box.nonnull():
+ op = ResOperation(rop.GUARD_NONNULL, [box])
+ extra_guards.append(op)
+ return
+ else:
+ raise VirtualStatesCantMatch("other not known to be nonnull")
+ elif other.level == LEVEL_NONNULL:
+ pass
+ elif other.level == LEVEL_KNOWNCLASS:
+ pass # implies nonnull
+ else:
+ assert other.level == LEVEL_CONSTANT
+ assert other.constbox
+ if not other.constbox.nonnull():
+ raise VirtualStatesCantMatch("constant is null")
+
+ def _generate_guards_knownclass(self, other, box, runtime_box,
extra_guards,
+ state):
+ cpu = state.cpu
+ if not isinstance(other, NotVirtualStateInfoPtr):
+ raise VirtualStatesCantMatch('trying to match ptr with non-ptr??!')
+ if other.level == LEVEL_UNKNOWN:
+ if (runtime_box and runtime_box.nonnull() and
+
self.known_class.same_constant(cpu.ts.cls_of_box(runtime_box))):
+ op = ResOperation(rop.GUARD_NONNULL_CLASS, [box,
self.known_class])
+ extra_guards.append(op)
+ else:
+ raise VirtualStatesCantMatch("other's class is unknown")
+ elif other.level == LEVEL_NONNULL:
+ if (runtime_box and self.known_class.same_constant(
+ cpu.ts.cls_of_box(runtime_box))):
+ op = ResOperation(rop.GUARD_CLASS, [box, self.known_class])
+ extra_guards.append(op)
+ else:
+ raise VirtualStatesCantMatch("other's class is unknown")
+ elif other.level == LEVEL_KNOWNCLASS:
+ if self.known_class.same_constant(other.known_class):
+ return
+ raise VirtualStatesCantMatch("classes don't match")
+ else:
+ assert other.level == LEVEL_CONSTANT
+ if (other.constbox.nonnull() and
+
self.known_class.same_constant(cpu.ts.cls_of_box(other.constbox))):
+ pass
+ else:
+ raise VirtualStatesCantMatch("classes don't match")
+
class VirtualState(object):
def __init__(self, state):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit