[pypy-svn] r53230 - in pypy/branch/jit-merging-logic/pypy/jit/timeshifter: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Tue Apr 1 14:04:28 CEST 2008


Author: cfbolz
Date: Tue Apr  1 14:04:26 2008
New Revision: 53230

Modified:
   pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rcontainer.py
   pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rtimeshift.py
   pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rvalue.py
   pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_merging.py
   pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_rcontainer.py
Log:
(cfbolz, arigo): use the new approach of remembering the last frozen box on each box to pass the new merging tests


Modified: pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rcontainer.py	(original)
+++ pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rcontainer.py	Tue Apr  1 14:04:26 2008
@@ -23,7 +23,8 @@
     _attrs_ = []
 
     def op_getfield(self, jitstate, fielddesc):
-        raise NotImplementedError
+        rgenop = jitstate.curbuilder.rgenop
+        return self.getfield_dont_generate_code(rgenop, fielddesc)
 
     def op_setfield(self, jitstate, fielddesc, valuebox):
         raise NotImplementedError
@@ -31,6 +32,9 @@
     def op_getsubstruct(self, jitstate, fielddesc):
         raise NotImplementedError
 
+    def getfield_dont_generate_code(self, rgenop, fielddesc):
+        raise NotImplementedError
+
 
 class VirtualContainer(AbstractContainer):
     _attrs_ = ('ownbox',)
@@ -639,6 +643,9 @@
             if self.virtualizable:
                 self.structdesc = StructTypeDesc(RGenOp, T)
             self.redboxcls = rvalue.ll_redboxcls(RESTYPE)
+            # fish for the FrozenConst subclass
+            dummybox = self.redboxcls(self.gv_default)
+            self.frozenconstcls = dummybox.FrozenConstCls
             
         self.immutable = deref(PTRTYPE)._hints.get('immutable', False)
 
@@ -909,15 +916,15 @@
             content_boxes[i] = content_boxes[i].replace(memo)
         self.ownbox = self.ownbox.replace(memo)
 
-    def op_getfield(self, jitstate, fielddesc):
-        return self.content_boxes[fielddesc.fieldindex]
-
     def op_setfield(self, jitstate, fielddesc, valuebox):
         self.content_boxes[fielddesc.fieldindex] = valuebox
 
     def op_getsubstruct(self, jitstate, fielddesc):
         return self.ownbox
 
+    def getfield_dont_generate_code(self, rgenop, fielddesc):
+        return self.content_boxes[fielddesc.fieldindex]
+
     def make_rti(self, jitstate, memo):
         try:
             return memo.containers[self]
@@ -1284,6 +1291,9 @@
             fielddesc.generate_set(jitstate, gv_ptr,
                                    valuebox.getgenvar(jitstate))
 
+    def getfield_dont_generate_code(self, rgenop, fielddesc):
+        xxx
+
     def op_ptreq(self, jitstate, otherbox, reverse):
         if self is otherbox.content:
             answer = True
@@ -1346,7 +1356,7 @@
     def __init__(self):
         self.data = []
 
-    def op_getfield(self, jitstate, fielddesc):
+    def getfield_dont_generate_code(self, rgenop, fielddesc):
         searchindex = fielddesc.fieldindex
         for index, box in self.data:
             if index == searchindex:

Modified: pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rtimeshift.py	Tue Apr  1 14:04:26 2008
@@ -166,9 +166,10 @@
             pass
         else:
             result = fielddesc.makebox(jitstate, resgv)
-            if argbox.future_usage is not None:
-                future_usage = argbox.future_usage.retrieve_child_usage(fielddesc)
-                result.future_usage = future_usage
+            fz = argbox.most_recent_frozen
+            if fz is not None:
+                newfz = fz.get_const_child(fielddesc, resgv)
+                result.most_recent_frozen = newfz
             return result
     return argbox.op_getfield(jitstate, fielddesc)
 

Modified: pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rvalue.py	(original)
+++ pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rvalue.py	Tue Apr  1 14:04:26 2008
@@ -14,8 +14,9 @@
 def freeze_memo():
     return Memo()
 
-def exactmatch_memo(force_merge=False):
+def exactmatch_memo(rgenop, force_merge=False):
     memo = Memo()
+    memo.rgenop = rgenop
     memo.partialdatamatch = {}
     memo.forget_nonzeroness = {}
     memo.force_merge=force_merge
@@ -346,30 +347,41 @@
         try:
             return boxmemo[self]
         except KeyError:
-            future_usage = self.retrieve_future_usage()
             content = self.content
-            if not self.genvar:
-                from pypy.jit.timeshifter import rcontainer
-                assert isinstance(content, rcontainer.VirtualContainer)
-                result = self.FrozenPtrVirtual(future_usage)
+            if content is None:
+                result = self.most_recent_frozen
+                if result is None:
+                    if self.genvar.is_const:
+                        result = self.FrozenPtrConst(self.genvar)
+                    elif content is None:
+                        result = self.FrozenPtrVar(self.known_nonzero)
+                    self.most_recent_frozen = result
+                else:
+                    # sanity-check the most_recent_frozen object
+                    if self.genvar.is_const:
+                        assert isinstance(result, self.FrozenPtrConst)
+                    else:
+                        assert isinstance(result, self.FrozenPtrVar)
                 boxmemo[self] = result
-                result.fz_content = content.freeze(memo)
-                return result
-            elif self.genvar.is_const:
-                result = self.FrozenPtrConst(future_usage, self.genvar)
-            elif content is None:
-                result = self.FrozenPtrVar(future_usage, self.known_nonzero)
             else:
-                # if self.content is not None, it's a PartialDataStruct
-                from pypy.jit.timeshifter import rcontainer
-                assert isinstance(content, rcontainer.PartialDataStruct)
-                result = self.FrozenPtrVarWithPartialData(future_usage,
-                                                          known_nonzero=True)
-                boxmemo[self] = result
-                result.fz_partialcontent = content.partialfreeze(memo)
-                return result
-            result.fz_access_info = self.access_info.copy()
-            boxmemo[self] = result
+                self.most_recent_frozen = None   # for now
+                if not self.genvar:
+                    from pypy.jit.timeshifter import rcontainer
+                    assert isinstance(content, rcontainer.VirtualContainer)
+                    result = self.FrozenPtrVirtual()
+                    # store the result in the memo before content.freeze(),
+                    # for recursive data structures
+                    boxmemo[self] = result
+                    result.fz_content = content.freeze(memo)
+                else:
+                    # if self.content is not None, it's a PartialDataStruct
+                    from pypy.jit.timeshifter import rcontainer
+                    assert isinstance(content, rcontainer.PartialDataStruct)
+                    result = self.FrozenPtrVarWithPartialData(known_nonzero=True)
+                    # store the result in the memo before content.freeze(),
+                    # for recursive data structures
+                    boxmemo[self] = result
+                    result.fz_partialcontent = content.partialfreeze(memo)
             return result
 
     def getgenvar(self, jitstate):
@@ -431,6 +443,19 @@
             assert self.content is not None
             self.content.op_setfield(jitstate, fielddesc, valuebox)
 
+    def getfield_dont_generate_code(self, rgenop, fielddesc):
+        if self.content is not None:
+            return self.content.getfield_dont_generate_code(rgenop, fielddesc)
+        elif self.genvar.is_const:
+            # this raises if something's wrong, never returns None right
+            try:
+                gv_result = fielddesc.perform_getfield(rgenop, self.genvar)
+            except rcontainer.SegfaultException:
+                return None
+            return fielddesc.redboxcls(gv_result)
+        else:
+            return None
+
     def remember_field(self, fielddesc, box):
         if self.genvar.is_const:
             return      # no point in remembering field then
@@ -481,6 +506,11 @@
             outgoingvarboxes.append(box)
             return False
 
+    def check_future_promotions(self, box, memo):
+        if (self.will_be_promoted and box.is_constant()
+            and not self.is_constant_equal(box)):
+            raise DontMerge
+
 
 class FrozenVar(FrozenValue):
 
@@ -513,6 +543,8 @@
         # XXX could return directly the original IntRedBox
         return IntRedBox(self.gv_const)
 
+IntRedBox.FrozenConstCls = FrozenIntConst
+
 
 class FrozenIntVar(FrozenVar):
 
@@ -540,6 +572,8 @@
     def unfreeze(self, incomingvarboxes, memo):
         return BoolRedBox(self.gv_const)
 
+BoolRedBox.FrozenConstCls = FrozenBoolConst
+
 
 class FrozenBoolVar(FrozenVar):
 
@@ -566,6 +600,8 @@
     def unfreeze(self, incomingvarboxes, memo):
         return DoubleRedBox(self.gv_const)
 
+DoubleRedBox.FrozenConstCls = FrozenDoubleConst
+
 
 class FrozenDoubleVar(FrozenVar):
 
@@ -582,8 +618,8 @@
 
 class FrozenAbstractPtrConst(FrozenConst):
 
-    def __init__(self, future_usage, gv_const):
-        FrozenConst.__init__(self, future_usage)
+    def __init__(self, gv_const):
+        FrozenConst.__init__(self)
         self.gv_const = gv_const
 
     def is_constant_equal(self, box):
@@ -600,6 +636,8 @@
         if self.is_constant_nullptr():
             memo.forget_nonzeroness[box] = None
         match = FrozenConst.exactmatch(self, box, outgoingvarboxes, memo)
+        if not match:
+            self.check_future_promotions(box, memo)
         #if not memo.force_merge and not match:
         #    from pypy.jit.timeshifter.rcontainer import VirtualContainer
         #    if isinstance(box.content, VirtualContainer):
@@ -609,18 +647,46 @@
     def unfreeze(self, incomingvarboxes, memo):
         return self.PtrRedBox(self.gv_const)
 
+    const_children = None
+
+    def get_const_child(self, fielddesc, gv_value):
+        # constant children of a constant immutable FrozenPtrConst
+        # are only used to track future promotions; they have no
+        # other effect on exactmatch().
+        if self.const_children is None:
+            self.const_children = {}
+        else:
+            try:
+                return self.const_children[fielddesc]
+            except KeyError:
+                pass
+        newfz = fielddesc.frozenconstcls(gv_value)
+        self.const_children[fielddesc] = newfz
+        return newfz
+
+    def check_future_promotions(self, box, memo):
+        FrozenConst.check_future_promotions(self, box, memo)
+        if self.const_children is not None:
+            for fielddesc, fz_child in self.const_children.items():
+                box_child = box.getfield_dont_generate_code(memo.rgenop, 
+                                                            fielddesc)
+                if box_child is not None:
+                    fz_child.check_future_promotions(box_child, memo)
+
 
 class FrozenPtrConst(FrozenAbstractPtrConst, LLTypeMixin):
     PtrRedBox = PtrRedBox
+PtrRedBox.FrozenConstCls = FrozenPtrConst
 
 class FrozenInstanceConst(FrozenAbstractPtrConst, OOTypeMixin):
     PtrRedBox = InstanceRedBox
+InstanceRedBox.FrozenConstCls = FrozenInstanceConst
 
 
 class AbstractFrozenPtrVar(FrozenVar):
 
-    def __init__(self, future_usage, known_nonzero):
-        FrozenVar.__init__(self, future_usage)
+    def __init__(self, known_nonzero):
+        FrozenVar.__init__(self)
         self.known_nonzero = known_nonzero
 
     def exactmatch(self, box, outgoingvarboxes, memo):

Modified: pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_merging.py
==============================================================================
--- pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_merging.py	(original)
+++ pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_merging.py	Tue Apr  1 14:04:26 2008
@@ -32,23 +32,25 @@
         """We have a frozen constant 42 which gets a (no-op) promotion after
         it is frozen.  Then it should fail to merge with a live constant 43.
         """
+        rgenop = FakeRGenOp()
+
         gc = FakeGenConst(42)
         box = rvalue.IntRedBox(gc)
         frozen = box.freeze(rvalue.freeze_memo())
         assert box.most_recent_frozen is not None    # attached by freeze()
         box.see_promote()
 
-        memo = rvalue.exactmatch_memo()
+        memo = rvalue.exactmatch_memo(rgenop)
         gv = FakeGenVar()
         newbox = rvalue.IntRedBox(gv)
         assert not frozen.exactmatch(newbox, [], memo)
 
-        memo = rvalue.exactmatch_memo()
+        memo = rvalue.exactmatch_memo(rgenop)
         gc2 = FakeGenConst(43)
         newbox = rvalue.IntRedBox(gc2)
         py.test.raises(rvalue.DontMerge, frozen.exactmatch, newbox, [], memo)
 
-        memo = rvalue.exactmatch_memo()
+        memo = rvalue.exactmatch_memo(rgenop)
         gc3 = FakeGenConst(42)
         newbox = rvalue.IntRedBox(gc3)
         assert frozen.exactmatch(newbox, [], memo)
@@ -57,18 +59,20 @@
         """We have a frozen variable which gets promoted after
         it is frozen.  Then it should fail to merge with any live constant.
         """
+        rgenop = FakeRGenOp()
+
         gv = FakeGenVar()
         box = rvalue.IntRedBox(gv)
         frozen = box.freeze(rvalue.freeze_memo())
         assert box.most_recent_frozen is not None    # attached by freeze()
         box.see_promote()
 
-        memo = rvalue.exactmatch_memo()
+        memo = rvalue.exactmatch_memo(rgenop)
         gv2 = FakeGenVar()
         newbox = rvalue.IntRedBox(gv2)
         assert frozen.exactmatch(newbox, [], memo)
 
-        memo = rvalue.exactmatch_memo()
+        memo = rvalue.exactmatch_memo(rgenop)
         gc = FakeGenConst(43)
         newbox = rvalue.IntRedBox(gc)
         py.test.raises(rvalue.DontMerge, frozen.exactmatch, newbox, [], memo)
@@ -77,6 +81,8 @@
         """In the merging logic, frozen boxes ignore promotions that
         occurred before the freezing.
         """
+        rgenop = FakeRGenOp()
+
         gc = FakeGenConst(42)
         box = rvalue.IntRedBox(gc)
         box.freeze(rvalue.freeze_memo())
@@ -85,12 +91,12 @@
 
         frozen = box.freeze(rvalue.freeze_memo())
 
-        memo = rvalue.exactmatch_memo()
+        memo = rvalue.exactmatch_memo(rgenop)
         gv = FakeGenVar()
         newbox = rvalue.IntRedBox(gv)
         assert not frozen.exactmatch(newbox, [], memo)
 
-        memo = rvalue.exactmatch_memo()
+        memo = rvalue.exactmatch_memo(rgenop)
         gc2 = FakeGenConst(43)
         newbox = rvalue.IntRedBox(gc2)
         assert not frozen.exactmatch(newbox, [], memo)
@@ -100,6 +106,8 @@
         there is an incoming live s2 for which we already know the value of
         s2.x, and for which the merge would loose that information.
         """
+        rgenop = FakeRGenOp()
+
         prebuilt_s = lltype.malloc(self.STRUCT)
         prebuilt_s.x = 42
 
@@ -112,21 +120,21 @@
 
         x_box = rtimeshift.gengetfield(jitstate, False, self.fielddesc, box)
         assert x_box.genvar.revealconst(lltype.Signed) == 42
-        assert x_box.future_usage is not None   # attached by gengetfield()
+        assert x_box.most_recent_frozen is not None # attached by gengetfield()
         x_box.see_promote()
 
-        memo = rvalue.exactmatch_memo()
+        memo = rvalue.exactmatch_memo(rgenop)
         assert frozen.exactmatch(box, [], memo)
 
         prebuilt_s2 = lltype.malloc(self.STRUCT)
         prebuilt_s2.x = 42
         box2 = rvalue.PtrRedBox(FakeGenConst(prebuilt_s2))
-        memo = rvalue.exactmatch_memo()
+        memo = rvalue.exactmatch_memo(rgenop)
         assert not frozen.exactmatch(box2, [], memo)
         # ^^^no DontMerge because box2.x is equal, so we don't loose its value
 
         prebuilt_s3 = lltype.malloc(self.STRUCT)
         prebuilt_s3.x = 43
         box3 = rvalue.PtrRedBox(FakeGenConst(prebuilt_s3))
-        memo = rvalue.exactmatch_memo()
+        memo = rvalue.exactmatch_memo(rgenop)
         py.test.raises(rvalue.DontMerge, frozen.exactmatch, box3, [], memo)

Modified: pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_rcontainer.py
==============================================================================
--- pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_rcontainer.py	(original)
+++ pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_rcontainer.py	Tue Apr  1 14:04:26 2008
@@ -3,7 +3,7 @@
 from pypy.rpython.lltypesystem import lltype
 from pypy.jit.timeshifter import rvalue, rcontainer
 from pypy.jit.timeshifter.test.support import FakeJITState, FakeGenVar
-from pypy.jit.timeshifter.test.support import FakeGenConst
+from pypy.jit.timeshifter.test.support import FakeGenConst, FakeRGenOp
 from pypy.jit.timeshifter.test.support import signed_kind
 from pypy.jit.timeshifter.test.support import vmalloc, makebox
 from pypy.jit.timeshifter.test.support import getfielddesc
@@ -42,9 +42,10 @@
         # of 'box' that correspond to FrozenVar placeholders in frozenbox.
         # Otherwise, it is the list of subboxes of 'box' that should be
         # generalized to become variables.
+        rgenop = FakeRGenOp()
         outgoingvarboxes = []
         res = frozenbox.exactmatch(box, outgoingvarboxes,
-                                   rvalue.exactmatch_memo())
+                                   rvalue.exactmatch_memo(rgenop))
         assert outgoingvarboxes == expected_outgoing
         return res
 


More information about the pypy-svn mailing list