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

cfbolz at codespeak.net cfbolz at codespeak.net
Tue Apr 1 10:51:17 CEST 2008


Author: cfbolz
Date: Tue Apr  1 10:51:16 2008
New Revision: 53227

Modified:
   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/support.py
   pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_merging.py
Log:
(arigo, cfbolz yesterday)  Intermediate check-in breaking everything,
I'd like to expriment a bit differently from there.


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 10:51:16 2008
@@ -165,7 +165,11 @@
         except rcontainer.SegfaultException:
             pass
         else:
-            return fielddesc.makebox(jitstate, resgv)
+            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
+            return result
     return argbox.op_getfield(jitstate, fielddesc)
 
 def gensetfield(jitstate, fielddesc, destbox, valuebox):

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 10:51:16 2008
@@ -47,12 +47,22 @@
         return gv.revealconst(ootype.Object)
 
 class FutureUsage(object):
-    promote_timestamp = 0
+    def __init__(self):
+        self.promote_timestamp = 0
+        self.children = {}
 
     def see_promote(self, timestamp):
         if timestamp > self.promote_timestamp:
             self.promote_timestamp = timestamp
 
+    def retrieve_child_usage(self, fielddesc):
+        try:
+            return self.children[fielddesc]
+        except KeyError:
+            future_usage = FutureUsage()
+            self.children[fielddesc] = future_usage
+            return future_usage
+
 
 class RedBox(object):
     _attrs_ = ['genvar', 'future_usage']
@@ -350,23 +360,25 @@
         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()
+                result = self.FrozenPtrVirtual(future_usage)
                 boxmemo[self] = result
                 result.fz_content = content.freeze(memo)
                 return result
             elif self.genvar.is_const:
-                result = self.FrozenPtrConst(self.genvar)
+                result = self.FrozenPtrConst(future_usage, self.genvar)
             elif content is None:
-                result = self.FrozenPtrVar(self.known_nonzero)
+                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(known_nonzero=True)
+                result = self.FrozenPtrVarWithPartialData(future_usage,
+                                                          known_nonzero=True)
                 boxmemo[self] = result
                 result.fz_partialcontent = content.partialfreeze(memo)
                 return result
@@ -473,9 +485,20 @@
         return False
 
     def check_timestamp(self, box, memo):
-        if (box.is_constant() and 
-            self.future_usage.promote_timestamp > memo.frozen_timestamp):
-            raise DontMerge
+        fu = self.future_usage
+        if fu is not None:
+            if (box.is_constant() and
+                fu.promote_timestamp > memo.frozen_timestamp):
+                raise DontMerge
+            if fu.children:
+                assert isinstance(box, AbstractPtrRedBox)
+                for fielddesc, fuchild in fu.children.items():
+                    frozenchild = self.maybe_get_child_box(fielddesc)
+                    boxchild = box.maybe_get_child_box(fielddesc)
+                    if frozenchild is not None and boxchild is not None:
+                        assert frozenchild.future_usage is fuchild
+                        frozenchild.check_timestamp(boxchild, memo)
+                    # XXX use the memo here too!
 
 
 class FrozenConst(FrozenValue):
@@ -589,7 +612,8 @@
 
 class FrozenAbstractPtrConst(FrozenConst):
 
-    def __init__(self, gv_const):
+    def __init__(self, future_usage, gv_const):
+        FrozenConst.__init__(self, future_usage)
         self.gv_const = gv_const
 
     def is_constant_equal(self, box):
@@ -606,15 +630,19 @@
         if self.is_constant_nullptr():
             memo.forget_nonzeroness[box] = None
         match = FrozenConst.exactmatch(self, box, outgoingvarboxes, memo)
-        if not memo.force_merge and not match:
-            from pypy.jit.timeshifter.rcontainer import VirtualContainer
-            if isinstance(box.content, VirtualContainer):
-                raise DontMerge   # XXX recursive data structures?
+        #if not memo.force_merge and not match:
+        #    from pypy.jit.timeshifter.rcontainer import VirtualContainer
+        #    if isinstance(box.content, VirtualContainer):
+        #        raise DontMerge   # XXX recursive data structures?
         return match
 
     def unfreeze(self, incomingvarboxes, memo):
         return self.PtrRedBox(self.gv_const)
 
+    def maybe_get_child_box(self, fielddesc):
+        XXX  # pfpfpfpfpf no fun at all! we make a non-frozen box and freeze it? uh how do we make the non-frozen box?
+        fielddesc.makebox(fielddesc.perform_getfield(rgenop:-(, self.gv_const)) # in theory
+                # :-( :-( :-(
 
 class FrozenPtrConst(FrozenAbstractPtrConst, LLTypeMixin):
     PtrRedBox = PtrRedBox
@@ -625,7 +653,8 @@
 
 class AbstractFrozenPtrVar(FrozenVar):
 
-    def __init__(self, known_nonzero):
+    def __init__(self, future_usage, known_nonzero):
+        FrozenVar.__init__(self, future_usage)
         self.known_nonzero = known_nonzero
 
     def exactmatch(self, box, outgoingvarboxes, memo):

Modified: pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/support.py
==============================================================================
--- pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/support.py	(original)
+++ pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/support.py	Tue Apr  1 10:51:16 2008
@@ -33,6 +33,9 @@
     def constPrebuiltGlobal(value):
         return FakeGenConst(value)
 
+    def genconst(self, value):
+        return FakeGenConst(value)
+
 
 class FakeBuilder(object):
     ops_with_no_retval = set(['setfield'])

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 10:51:16 2008
@@ -1,20 +1,17 @@
-"""<arigato> [merge point including x]
-<arigato> promote(x)
-<cfbolz> then the frozen x has a futureusage
-<arigato> yes
-<cfbolz> isn't this example too easy?
-<cfbolz> I mean, in which case would we want to prevent a merge?
-<arigato> it's a start
-<arigato> no, it shows the essential bit
-<arigato> if x was initially a constant(5), then we don't want to merge with any other value
-<arigato> if x was initially a variable, then we don't want to merge with any constant at all
+"""
+<cfbolz> so, we have a frozen _variable_ s
+<cfbolz> and do promote(s.x)
+<cfbolz> and try to merge it with a virtual s
+<arigato> it looks a bit strange but I suppose that 's.x' should also create {'x': FutureUsage()} in the FutureUsage() of s
+<cfbolz> yes, I fear so
+<arigato> so, we get a virtual s to merge...
 """
 
 import py
 from pypy.rpython.lltypesystem import lltype
-from pypy.jit.timeshifter import rvalue, rcontainer
+from pypy.jit.timeshifter import rvalue, rcontainer, rtimeshift
 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
@@ -23,7 +20,8 @@
 class TestMerging:
 
     def setup_class(cls):
-        cls.STRUCT = lltype.GcStruct("S", ("x", lltype.Signed))
+        cls.STRUCT = lltype.GcStruct("S", ("x", lltype.Signed),
+                                     hints={'immutable': True})
         cls.fielddesc = getfielddesc(cls.STRUCT, "x")
         FORWARD = lltype.GcForwardReference()
         cls.NESTEDSTRUCT = lltype.GcStruct('dummy', ("foo", lltype.Signed),
@@ -31,6 +29,9 @@
         FORWARD.become(cls.NESTEDSTRUCT)
 
     def test_promote_const(self):
+        """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.
+        """
         gc = FakeGenConst(42)
         box = rvalue.IntRedBox(gc)
         frozen = box.freeze(rvalue.freeze_memo())
@@ -49,6 +50,9 @@
         py.test.raises(rvalue.DontMerge, frozen.exactmatch, newbox, [], memo)
 
     def test_promote_var(self):
+        """We have a frozen variable which gets promoted after
+        it is frozen.  Then it should fail to merge with any live constant.
+        """
         gv = FakeGenVar()
         box = rvalue.IntRedBox(gv)
         frozen = box.freeze(rvalue.freeze_memo())
@@ -67,6 +71,9 @@
         py.test.raises(rvalue.DontMerge, frozen.exactmatch, newbox, [], memo)
 
     def test_promotebefore_freeze_const(self):
+        """In the merging logic, frozen boxes ignore promotions that
+        occurred before the freezing.
+        """
         gc = FakeGenConst(42)
         box = rvalue.IntRedBox(gc)
         box.freeze(rvalue.freeze_memo())
@@ -85,3 +92,40 @@
         gc2 = FakeGenConst(43)
         newbox = rvalue.IntRedBox(gc2)
         assert not frozen.exactmatch(newbox, [], memo)
+
+    def test_promote_field_of_constant_immutable(self):
+        """We freeze s then promote s.x.  This should prevent a merge where
+        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.
+        """
+        prebuilt_s = lltype.malloc(self.STRUCT)
+        prebuilt_s.x = 42
+
+        gc = FakeGenConst(prebuilt_s)
+        box = rvalue.PtrRedBox(gc)
+        frozen = box.freeze(rvalue.freeze_memo())
+        assert box.future_usage is not None # attached by freeze
+        frozen_timestamp = 0
+
+        jitstate = FakeJITState()
+
+        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()
+        x_box.future_usage.see_promote(timestamp=1)
+
+        memo = rvalue.exactmatch_memo(frozen_timestamp=frozen_timestamp)
+        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(frozen_timestamp=frozen_timestamp)
+        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(frozen_timestamp=frozen_timestamp)
+        py.test.raises(rvalue.DontMerge, frozen.exactmatch, box3, [], memo)



More information about the Pypy-commit mailing list