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

Reply via email to