[pypy-commit] pypy value-classes: Attempted support for unpacking constant pointers
sbauman
pypy.commits at gmail.com
Thu Sep 29 17:05:09 EDT 2016
Author: Spenser Bauman <sabauma at gmail.com>
Branch: value-classes
Changeset: r87456:48e89a5c1a07
Date: 2016-09-29 17:04 -0400
http://bitbucket.org/pypy/pypy/changeset/48e89a5c1a07/
Log: Attempted support for unpacking constant pointers
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -328,7 +328,8 @@
guard.rd_resume_position = patchguardop.rd_resume_position
guard.setdescr(compile.ResumeAtPositionDescr())
self.send_extra_operation(guard)
- except VirtualStatesCantMatch:
+ except VirtualStatesCantMatch as e:
+ print "*** failing with: ", e.msg
continue
# When force_boxes == True, creating the virtual args can fail when
@@ -337,8 +338,9 @@
try:
args, virtuals = target_virtual_state.make_inputargs_and_virtuals(
args, self.optimizer, force_boxes=force_boxes)
- except VirtualStatesCantMatch:
+ except VirtualStatesCantMatch as e:
assert force_boxes
+ print "*** failing with: ", e.msg
virtual_state = self.get_virtual_state(args)
continue
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
@@ -219,7 +219,7 @@
@specialize.argtype(4)
def getfield(self, box, info, descr, optimizer):
assert isinstance(info, AbstractStructPtrInfo)
- field = info._fields[descr.get_index()]
+ field = info.getfield(descr, optimizer)
if field is not None:
return field
opnum = rop.getfield_for_descr(descr)
@@ -229,12 +229,18 @@
else:
from rpython.jit.metainterp.optimizeopt import Optimizer
assert isinstance(optimizer, Optimizer)
- optimizer.emit_operation(getfield)
- info._fields[descr.get_index()] = getfield
+ optimizer.send_extra_operation(getfield)
+ info.setfield(descr, None, getfield)
return getfield
def make_virtual_copy(self, box, info, optimizer):
optvirtualize = optimizer.optvirtualize
+
+ if isinstance(box, ConstPtr):
+ # Wrap const pointers in SAME_AS_R operation to cloning via
+ # make_virtual, which expects a ResOperation with an opnum.
+ box = ResOperation(rop.SAME_AS_R, [box])
+
opinfo = optvirtualize.make_virtual(self.known_class, box, self.typedescr)
for i in range(len(info._fields)):
descr = self.fielddescrs[i]
@@ -250,6 +256,9 @@
return AbstractVirtualStructStateInfo.enum_forced_boxes(
self, boxes, box, optimizer, force_boxes)
+ if isinstance(info, ConstPtrInfo):
+ optheap = optimizer.optimizer.optheap
+ info = info._get_info(self.typedescr, optheap)
assert isinstance(info, AbstractStructPtrInfo)
# TODO: Do we need to create a new object via NEW_WITH_VTABLE, or will the
@@ -273,7 +282,7 @@
assert isinstance(other, NotVirtualStateInfoPtr)
if not self.typedescr.is_value_class():
- raise VirtualStatesCantMatch("different kinds of structs")
+ raise VirtualStatesCantMatch("_generate_guards_non_virtual: different kinds of structs")
# raise VirtualStatesCantMatch("different kinds of structs")
# TODO: Probably should rename state.extra_guards to extra_ops
@@ -290,7 +299,7 @@
extra_guards.append(op)
elif other.level == LEVEL_KNOWNCLASS:
if not self.known_class.same_constant(other.known_class):
- raise VirtualStatesCantMatch("classes don't match")
+ raise VirtualStatesCantMatch("_generate_guards_non_virtual: classes don't match")
else:
assert other.level == LEVEL_CONSTANT
known = self.known_class
@@ -298,7 +307,7 @@
if const.nonnull() and known.same_constant(cpu.ts.cls_of_box(const)):
pass
else:
- raise VirtualStatesCantMatch("classes don't match")
+ raise VirtualStatesCantMatch("_generate_guards_non_virtual: classes don't match")
# Things to do...
# 1. Generate new_with_vtable operation to allocate the new virtual object
@@ -308,11 +317,13 @@
# non-virtual object which we are promoting to a virtual. How do we
# generate this new virtual state so we can operate recursively)
+ optimizer = state.optimizer
if runtime_box is not None:
- opinfo = state.optimizer.getptrinfo(box)
- if opinfo is not None and not isinstance(opinfo, AbstractStructPtrInfo):
- assert isinstance(opinfo, ConstPtrInfo)
- raise VirtualStatesCantMatch("cannot yet handle const pointers")
+ opinfo = optimizer.getptrinfo(box)
+ if isinstance(opinfo, ConstPtrInfo):
+ optheap = optimizer.optheap
+ opinfo = opinfo._get_info(self.typedescr, optheap)
+ assert opinfo is None or isinstance(opinfo, AbstractStructPtrInfo)
else:
opinfo = None
diff --git a/rpython/jit/metainterp/test/test_virtual.py b/rpython/jit/metainterp/test/test_virtual.py
--- a/rpython/jit/metainterp/test/test_virtual.py
+++ b/rpython/jit/metainterp/test/test_virtual.py
@@ -1087,33 +1087,39 @@
self.meta_interp(f, [])
def test_avoid_preamble_4(self):
- driver = JitDriver(greens=[], reds=['i', 'val'])
+ driver = JitDriver(greens=[], reds=['i', 'acc', 'val'])
class X(object):
_value_class_ = True
def __init__(self, v):
self.v = v
const = X(5)
+ arr = [None]
def f():
# Prevent all retracing of side exits. Ensures that the unroll
# optimizer will attempt to jump to either the preamble or loop.
set_param(driver, 'retrace_limit', -1)
set_param(driver, 'threshold', 1)
- val = X(0)
- i = 0
+ val = X(0)
+ acc = 0
+ i = 0
while i < 17:
- driver.can_enter_jit(i=i, val=val)
- driver.jit_merge_point(i=i, val=val)
+ driver.can_enter_jit(i=i, acc=acc, val=val)
+ driver.jit_merge_point(i=i, acc=acc, val=val)
# Logical & rather than comparison to confuse range analysis.
# Test only succeeds on the first 2 iterations
+ arr[0] = val
if i & -2 == 0:
val = X(i)
else:
val = const
+ acc += val.v
i += 1
return 0
self.meta_interp(f, [])
+ loop = get_stats().loops[0]
+ import pdb; pdb.set_trace()
def test_aliased_virtual_states(self):
# All cases are covered when forcing one component of the virtual state
@@ -1150,6 +1156,30 @@
self.meta_interp(f, [])
# assert did not crash
+ def test_double_allocation(self):
+ driver = JitDriver(greens=[], reds=['i'])
+
+ class X(object):
+ _value_class_ = True
+ def __init__(self, v):
+ self.v = v
+
+ array = [None, None]
+ def f():
+ # Prevent all retracing of side exits. Ensures that the unroll
+ # optimizer will attempt to jump to either the preamble or loop.
+ set_param(driver, 'retrace_limit', -1)
+ set_param(driver, 'threshold', 1)
+ i = 0
+ while i < 17:
+ driver.can_enter_jit(i=i)
+ driver.jit_merge_point(i=i)
+ array[0] = X(i)
+ array[1] = X(i)
+ i += 1
+ return 0
+
+ self.meta_interp(f, [])
class VirtualMiscTests:
def test_multiple_equal_virtuals(self):
More information about the pypy-commit
mailing list