Author: Maciej Fijalkowski <[email protected]>
Branch: optresult-unroll
Changeset: r78513:7e74715499f8
Date: 2015-07-09 18:54 +0200
http://bitbucket.org/pypy/pypy/changeset/7e74715499f8/
Log: start writing enum_forced_boxes
diff --git a/rpython/jit/metainterp/optimizeopt/info.py
b/rpython/jit/metainterp/optimizeopt/info.py
--- a/rpython/jit/metainterp/optimizeopt/info.py
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -77,6 +77,11 @@
self.last_guard_pos = len(optimizer._newoperations) - 1
assert self.get_last_guard(optimizer).is_guard()
+ def visitor_walk_recursive(self, instbox, visitor, optimizer):
+ if visitor.already_seen_virtual(instbox):
+ return
+ return self._visitor_walk_recursive(instbox, visitor, optimizer)
+
class AbstractVirtualPtrInfo(NonNullPtrInfo):
_attrs_ = ('_cached_vinfo', 'vdescr')
# XXX merge _cached_vinfo with vdescr
@@ -141,9 +146,7 @@
if optforce.optheap is not None:
optforce.optheap.register_dirty_field(flddescr, self)
- def visitor_walk_recursive(self, instbox, visitor, optimizer):
- if visitor.already_seen_virtual(instbox):
- return
+ def _visitor_walk_recursive(self, instbox, visitor, optimizer):
lst = self.vdescr.get_all_fielddescrs()
assert self.is_virtual()
visitor.register_virtual_fields(instbox,
@@ -174,6 +177,7 @@
assert self.is_virtual()
return visitor.visit_virtual(self.vdescr, fielddescrs)
+
class StructPtrInfo(AbstractStructPtrInfo):
def __init__(self, vdescr=None):
self.vdescr = vdescr
@@ -185,7 +189,7 @@
return visitor.visit_vstruct(self.vdescr, fielddescrs)
class AbstractRawPtrInfo(AbstractVirtualPtrInfo):
- def visitor_walk_recursive(self, op, visitor, optimizer):
+ def _visitor_walk_recursive(self, op, visitor, optimizer):
raise NotImplementedError("abstract")
@specialize.argtype(1)
@@ -228,7 +232,7 @@
[op, ConstInt(offset), itembox], descr=descr)
optforce.emit_operation(op)
- def visitor_walk_recursive(self, op, visitor, optimizer):
+ def _visitor_walk_recursive(self, op, visitor, optimizer):
itemboxes = self.buffer.values
visitor.register_virtual_fields(op, itemboxes)
# there can be no virtuals stored in raw buffer
@@ -263,7 +267,7 @@
def _force_elements(self, op, optforce, descr):
raise Exception("implement me")
- def visitor_walk_recursive(self, op, visitor, optimizer):
+ def _visitor_walk_recursive(self, op, visitor, optimizer):
source_op = optimizer.get_box_replacement(op.getarg(0))
visitor.register_virtual_fields(op, [source_op])
self.parent.visitor_walk_recursive(source_op, visitor, optimizer)
@@ -331,7 +335,7 @@
def getlength(self):
return self.length
- def visitor_walk_recursive(self, instbox, visitor, optimizer):
+ def _visitor_walk_recursive(self, instbox, visitor, optimizer):
itemops = [optimizer.get_box_replacement(item)
for item in self._items]
visitor.register_virtual_fields(instbox, itemops)
@@ -385,7 +389,7 @@
# if it does, we would need a fix here
i += 1
- def visitor_walk_recursive(self, instbox, visitor, optimizer):
+ def _visitor_walk_recursive(self, instbox, visitor, optimizer):
itemops = [optimizer.get_box_replacement(item)
for item in self._items]
visitor.register_virtual_fields(instbox, itemops)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py
b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py
@@ -2,19 +2,29 @@
""" More direct tests for unrolling
"""
+import py
+
from rpython.jit.metainterp.optimizeopt.test.test_util import BaseTest,\
LLtypeMixin
from rpython.jit.metainterp.history import (TreeLoop, ConstInt,
JitCellToken, TargetToken)
-from rpython.jit.metainterp.resoperation import rop, ResOperation
+from rpython.jit.metainterp.resoperation import rop, ResOperation,\
+ InputArgRef
from rpython.jit.metainterp.compile import LoopCompileData
from rpython.jit.metainterp.optimizeopt.virtualstate import \
NotVirtualStateInfo, LEVEL_CONSTANT, LEVEL_UNKNOWN, LEVEL_KNOWNCLASS,\
- LEVEL_NONNULL
+ VirtualStateInfo, BadVirtualState
+from rpython.jit.metainterp.optimizeopt import info
from rpython.jit.codewriter import heaptracker
class FakeOptimizer(object):
optearlyforce = None
+
+ def getptrinfo(self, box):
+ return box.get_forwarded()
+
+ def get_box_replacement(self, box):
+ return box
class BaseTestUnroll(BaseTest, LLtypeMixin):
enable_opts =
"intbounds:rewrite:virtualize:string:earlyforce:pure:heap:unroll"
@@ -83,7 +93,33 @@
es, loop, preamble = self.optimize(loop)
p0 = preamble.inputargs[0]
expected_class = heaptracker.adr2int(self.node_vtable_adr)
- assert expected_class ==es.exported_infos[p0]._known_class.getint()
+ assert expected_class == es.exported_infos[p0]._known_class.getint()
vs = es.virtual_state
assert vs.state[0].level == LEVEL_KNOWNCLASS
assert vs.state[0].known_class.getint() == expected_class
+
+ def test_virtual(self):
+ loop = """
+ [p1, p2]
+ p0 = new_with_vtable(descr=nodesize)
+ setfield_gc(p0, 1, descr=valuedescr)
+ setfield_gc(p0, p1, descr=nextdescr)
+ jump(p0, p0)
+ """
+ es, loop, preamble = self.optimize(loop)
+ vs = es.virtual_state
+ assert vs.state[0] is vs.state[1]
+ assert isinstance(vs.state[0], VirtualStateInfo)
+ assert isinstance(vs.state[0].fieldstate[0], NotVirtualStateInfo)
+ assert vs.state[0].fieldstate[0].level == LEVEL_CONSTANT
+ assert isinstance(vs.state[0].fieldstate[3], NotVirtualStateInfo)
+ assert vs.state[0].fieldstate[3].level == LEVEL_UNKNOWN
+ assert vs.numnotvirtuals == 1
+ p = InputArgRef()
+ py.test.raises(BadVirtualState, vs.make_inputargs, [p, p],
+ FakeOptimizer())
+ ptrinfo = info.StructPtrInfo(self.nodesize)
+ p2 = InputArgRef()
+ ptrinfo._fields = [None, None, None, p2]
+ p.set_forwarded(ptrinfo)
+ vs.make_inputargs([p, p], FakeOptimizer())
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
@@ -10,7 +10,8 @@
from rpython.rtyper.lltypesystem import lltype, llmemory
from rpython.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin,
BaseTest, \
equaloplists
-from rpython.jit.metainterp.optimizeopt.intutils import IntBound, ConstIntBound
+from rpython.jit.metainterp.optimizeopt.intutils import IntBound,\
+ ConstIntBound, IntLowerBound, IntUpperBound, IntUnbounded
from rpython.jit.metainterp.history import TreeLoop, JitCellToken
from rpython.jit.metainterp.optimizeopt.test.test_optimizeopt import
FakeMetaInterpStaticData
from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer
@@ -86,6 +87,7 @@
vs = VirtualState([info0])
assert vs.make_inputargs(args, optimizer) == args
info0.level = LEVEL_CONSTANT
+ vs = VirtualState([info0])
assert vs.make_inputargs(args, optimizer) == []
def test_position_generalization(self):
@@ -148,11 +150,10 @@
if i != j:
assert not isgeneral('r', inorder[j], 'r', inorder[i])
- value1 = IntOptValue(BoxInt())
- value2 = IntOptValue(BoxInt())
- value2.intbound.make_lt(IntBound(10, 10))
- assert isgeneral(value1, value2)
- assert not isgeneral(value2, value1)
+ i1 = IntLowerBound(10)
+ i2 = IntUnbounded()
+ assert isgeneral('i', i1, 'i', i2)
+ assert not isgeneral('i', i2, 'i', i1)
assert isgeneral(OptValue(ConstInt(7)), OptValue(ConstInt(7)))
S = lltype.GcStruct('S')
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
@@ -1,7 +1,6 @@
from rpython.jit.metainterp.walkvirtual import VirtualVisitor
from rpython.jit.metainterp.history import (ConstInt, Const,
ConstPtr, ConstFloat)
-from rpython.jit.metainterp.optimizeopt import virtualize
from rpython.jit.metainterp.optimizeopt.intutils import IntUnbounded
from rpython.jit.metainterp.resoperation import rop, ResOperation,\
AbstractInputArg
@@ -133,23 +132,23 @@
def _generalization_of_structpart(self, other):
raise NotImplementedError
- def enum_forced_boxes(self, boxes, value, optimizer):
- if not isinstance(value, virtualize.AbstractVirtualStructValue):
- raise BadVirtualState
- if not value.is_virtual():
- raise BadVirtualState
+ def enum_forced_boxes(self, boxes, box, optimizer):
+ info = optimizer.getptrinfo(box)
+ box = optimizer.get_box_replacement(box)
+ if info is None or not info.is_virtual():
+ raise BadVirtualState()
for i in range(len(self.fielddescrs)):
- try:
- v = value._fields[self.fielddescrs[i]]
- except KeyError:
- raise BadVirtualState
- s = self.fieldstate[i]
- if s.position > self.position:
- s.enum_forced_boxes(boxes, v, optimizer)
+ state = self.fieldstate[i]
+ if not state:
+ continue
+ if state.position > self.position:
+ fieldbox = info._fields[i]
+ state.enum_forced_boxes(boxes, fieldbox, optimizer)
def _enum(self, virtual_state):
for s in self.fieldstate:
- s.enum(virtual_state)
+ if s:
+ s.enum(virtual_state)
class VirtualStateInfo(AbstractVirtualStructStateInfo):
@@ -200,6 +199,7 @@
v, state)
def enum_forced_boxes(self, boxes, value, optimizer):
+ xxx
if not isinstance(value, virtualize.VArrayValue):
raise BadVirtualState
if not value.is_virtual():
@@ -258,6 +258,7 @@
s.enum(virtual_state)
def enum_forced_boxes(self, boxes, value, optimizer):
+ xxx
if not isinstance(value, virtualize.VArrayStructValue):
raise BadVirtualState
if not value.is_virtual():
@@ -422,16 +423,18 @@
return
raise VirtualStatesCantMatch("intbounds don't match")
- def enum_forced_boxes(self, boxes, value, optimizer):
+ def enum_forced_boxes(self, boxes, box, optimizer):
if self.level == LEVEL_CONSTANT:
return
assert 0 <= self.position_in_notvirtuals
- if optimizer:
- box = value.force_box(optimizer)
- else:
- if value.is_virtual():
+ #if optimizer:
+ # box = value.force_box(optimizer)
+ #else:
+ box = optimizer.get_box_replacement(box)
+ if box.type == 'r':
+ info = optimizer.getptrinfo(box)
+ if info and info.is_virtual():
raise BadVirtualState
- box = value.get_key_box()
boxes[self.position_in_notvirtuals] = box
def _enum(self, virtual_state):
@@ -505,34 +508,35 @@
return state
def make_inputargs(self, inputargs, optimizer, keyboxes=False):
- if optimizer.optearlyforce:
- optimizer = optimizer.optearlyforce
assert len(inputargs) == len(self.state)
- inpargs = []
- for i, state in enumerate(self.state):
- if state.level != LEVEL_CONSTANT:
- inpargs.append(inputargs[i])
- return inpargs
- inputargs = [None] * self.numnotvirtuals
+ #inpargs = []
+ #for i, state in enumerate(self.state):
+ # if not isinstance(state, NotVirtualStateInfo) or state.level !=
LEVEL_CONSTANT:
+ # inpargs.append(inputargs[i])
+ #return inpargs
+ boxes = [None] * self.numnotvirtuals
+ # XXX no longer correct as far as I can tell, maybe we should
+ # make the forcing more explicit somewhere else
# We try twice. The first time around we allow boxes to be forced
# which might change the virtual state if the box appear in more
# than one place among the inputargs.
- for i in range(len(values)):
- self.state[i].enum_forced_boxes(inputargs, values[i], optimizer)
- for i in range(len(values)):
- self.state[i].enum_forced_boxes(inputargs, values[i], None)
+ for i in range(len(inputargs)):
+ self.state[i].enum_forced_boxes(boxes, inputargs[i], optimizer)
+ #for i in range(len(values)):
+ # self.state[i].enum_forced_boxes(inputargs, values[i], None)
- if keyboxes:
- for i in range(len(values)):
- if not isinstance(self.state[i], NotVirtualStateInfo):
- box = values[i].get_key_box()
- assert not isinstance(box, Const)
- inputargs.append(box)
+ # not sure what are these guys doing
+ #if keyboxes:
+ # for i in range(len(values)):
+ # if not isinstance(self.state[i], NotVirtualStateInfo):
+ # box = values[i].get_key_box()
+ # assert not isinstance(box, Const)
+ # inputargs.append(box)
- assert None not in inputargs
+ assert None not in boxes
- return inputargs
+ return boxes
def debug_print(self, hdr='', bad=None, metainterp_sd=None):
if bad is None:
@@ -556,54 +560,63 @@
def already_seen_virtual(self, keybox):
return keybox in self.fieldboxes
- def getvalue(self, box):
- return self.optimizer.getvalue(box)
+ #def state(self, box):
+ # xxx
+ # value = self.getvalue(box)
+ # box = value.get_key_box()
+ # try:
+ # info = self.info[box]
+ # except KeyError:
+ # self.info[box] = info = value.visitor_dispatch_virtual_type(self)
+ # if value.is_virtual():
+ # flds = self.fieldboxes[box]
+ # info.fieldstate = [self.state_or_none(b, value) for b in flds]
+ # return info
- def state(self, box):
+ #def state_or_none(self, box, value):
+ # if box is None:
+ # box = value.get_missing_null_value().box
+ # return self.state(box)
+
+ def create_state_or_none(self, box, opt):
+ if box is None:
+ return None
+ return self.create_state(box, opt)
+
+ def create_state(self, box, opt):
+ box = opt.get_box_replacement(box)
+ try:
+ return self.info[box]
+ except KeyError:
+ pass
if box.type == 'r':
- xxxx
- return None
- value = self.getvalue(box)
- box = value.get_key_box()
- try:
- info = self.info[box]
- except KeyError:
- self.info[box] = info = value.visitor_dispatch_virtual_type(self)
- if value.is_virtual():
- flds = self.fieldboxes[box]
- info.fieldstate = [self.state_or_none(b, value) for b in flds]
- return info
-
- def state_or_none(self, box, value):
- if box is None:
- box = value.get_missing_null_value().box
- return self.state(box)
+ info = opt.getptrinfo(box)
+ if info is not None and info.is_virtual():
+ result = info.visitor_dispatch_virtual_type(self)
+ self.info[box] = result
+ info.visitor_walk_recursive(box, self, opt)
+ result.fieldstate = [self.create_state_or_none(b, opt)
+ for b in self.fieldboxes[box]]
+ else:
+ result = self.visit_not_virtual(box)
+ self.info[box] = result
+ elif box.type == 'i' or box.type == 'f':
+ result = self.visit_not_virtual(box)
+ self.info[box] = result
+ else:
+ assert False
+ return result
def get_virtual_state(self, jump_args):
self.optimizer.force_at_end_of_preamble()
- already_forced = {}
if self.optimizer.optearlyforce:
opt = self.optimizer.optearlyforce
else:
opt = self.optimizer
state = []
+ self.info = {}
for box in jump_args:
- box = opt.get_box_replacement(box)
- if box.type == 'r':
- info = opt.getptrinfo(box)
- if info is not None and info.is_virtual():
- xxx
- else:
- state.append(self.visit_not_virtual(box))
- elif box.type == 'i':
- intbound = opt.getintbound(box)
- state.append(self.visit_not_virtual(box))
- else:
- xxx
- #values = [self.getvalue(box).force_at_end_of_preamble(already_forced,
- # opt)
- # for box in jump_args]
-
+ state.append(self.create_state(box, opt))
return VirtualState(state)
def visit_not_virtual(self, box):
diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py
b/rpython/jit/metainterp/optimizeopt/vstring.py
--- a/rpython/jit/metainterp/optimizeopt/vstring.py
+++ b/rpython/jit/metainterp/optimizeopt/vstring.py
@@ -204,7 +204,7 @@
offsetbox = _int_add(string_optimizer, offsetbox, CONST_1)
return offsetbox
- def visitor_walk_recursive(self, instbox, visitor, optimizer):
+ def _visitor_walk_recursive(self, instbox, visitor, optimizer):
visitor.register_virtual_fields(instbox, self._chars)
@specialize.argtype(1)
@@ -248,7 +248,7 @@
def getstrlen(self, op, string_optimizer, mode, create_ops=True):
return self.lgtop
- def visitor_walk_recursive(self, instbox, visitor, optimizer):
+ def _visitor_walk_recursive(self, instbox, visitor, optimizer):
boxes = [self.s, self.start, self.lgtop]
visitor.register_virtual_fields(instbox, boxes)
opinfo = optimizer.getptrinfo(self.s)
@@ -309,7 +309,7 @@
targetbox, offsetbox, mode)
return offsetbox
- def visitor_walk_recursive(self, instbox, visitor, optimizer):
+ def _visitor_walk_recursive(self, instbox, visitor, optimizer):
# we don't store the lengthvalue in guards, because the
# guard-failed code starts with a regular STR_CONCAT again
leftbox = self.vleft
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit