[pypy-svn] r74675 - in pypy/branch/blackhole-improvement/pypy/jit: codewriter metainterp metainterp/test

arigo at codespeak.net arigo at codespeak.net
Sat May 22 13:27:33 CEST 2010


Author: arigo
Date: Sat May 22 13:27:31 2010
New Revision: 74675

Modified:
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/call.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/effectinfo.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_compile.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_optimizefindnode.py
Log:
Tweaks and fixes.


Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/call.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/call.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/call.py	Sat May 22 13:27:31 2010
@@ -7,7 +7,7 @@
 from pypy.jit.codewriter.jitcode import JitCode
 from pypy.jit.codewriter.effectinfo import VirtualizableAnalyzer
 from pypy.jit.codewriter.effectinfo import effectinfo_from_writeanalyze
-from pypy.jit.codewriter import effectinfo as ef
+from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.translator.simplify import get_funcobj, get_functype
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.translator.backendopt.canraise import RaiseAnalyzer
@@ -199,23 +199,23 @@
                                            "loop-invariant function!")
         # build the extraeffect
         if self.virtualizable_analyzer.analyze(op):
-            extraeffect = ef.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
+            extraeffect = EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
         elif loopinvariant:
-            extraeffect = ef.EF_LOOPINVARIANT
+            extraeffect = EffectInfo.EF_LOOPINVARIANT
         elif pure:
             # XXX check what to do about exceptions (also MemoryError?)
-            extraeffect = ef.EF_PURE
+            extraeffect = EffectInfo.EF_PURE
         elif self._canraise(op):
-            extraeffect = ef.EF_CAN_RAISE
+            extraeffect = EffectInfo.EF_CAN_RAISE
         else:
-            extraeffect = ef.EF_CANNOT_RAISE
+            extraeffect = EffectInfo.EF_CANNOT_RAISE
         #
         effectinfo = effectinfo_from_writeanalyze(
             self.readwrite_analyzer.analyze(op), self.cpu, extraeffect)
         #
         if pure or loopinvariant:
             assert effectinfo is not None
-            assert extraeffect != ef.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
+            assert extraeffect != EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
         #
         return self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS), RESULT,
                                     effectinfo)
@@ -229,7 +229,8 @@
 
     def calldescr_canraise(self, calldescr):
         effectinfo = calldescr.get_extra_info()
-        return effectinfo is None or effectinfo.extraeffect >= ef.EF_CAN_RAISE
+        return (effectinfo is None or
+                effectinfo.extraeffect >= EffectInfo.EF_CAN_RAISE)
 
     def found_jitdriver(self, jitdriver):
         if self.jitdriver is None:

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/effectinfo.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/effectinfo.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/effectinfo.py	Sat May 22 13:27:31 2010
@@ -4,17 +4,17 @@
 from pypy.rpython.ootypesystem import ootype
 from pypy.translator.backendopt.graphanalyze import BoolGraphAnalyzer
 
-# the 'extraeffect' field is one of the following values:
-EF_PURE                            = 0   # pure function (and cannot raise)
-EF_CANNOT_RAISE                    = 1   # a function which cannot raise
-EF_CAN_RAISE                       = 2   # normal function (can raise)
-EF_LOOPINVARIANT                   = 3   # special: call it only once per loop
-EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE = 4   # can raise and force virtualizables
-
 
 class EffectInfo(object):
     _cache = {}
 
+    # the 'extraeffect' field is one of the following values:
+    EF_PURE                            = 0 #pure function (and cannot raise)
+    EF_CANNOT_RAISE                    = 1 #a function which cannot raise
+    EF_CAN_RAISE                       = 2 #normal function (can raise)
+    EF_LOOPINVARIANT                   = 3 #special: call it only once per loop
+    EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE = 4 #can raise and force virtualizables
+
     def __new__(cls, readonly_descrs_fields,
                 write_descrs_fields, write_descrs_arrays,
                 extraeffect=EF_CAN_RAISE):
@@ -33,9 +33,10 @@
         return result
 
     def check_forces_virtual_or_virtualizable(self):
-        return self.extraeffect >= EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
+        return self.extraeffect >= self.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
 
-def effectinfo_from_writeanalyze(effects, cpu, extraeffect=EF_CAN_RAISE):
+def effectinfo_from_writeanalyze(effects, cpu,
+                                 extraeffect=EffectInfo.EF_CAN_RAISE):
     from pypy.translator.backendopt.writeanalyze import top_set
     if effects is top_set:
         return None

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py	Sat May 22 13:27:31 2010
@@ -42,8 +42,11 @@
         #
         def do_rename(var, var_or_const):
             renamings[var] = var_or_const
-            if isinstance(var_or_const, Constant):
-                renamings_constants[var] = var_or_const
+            if (isinstance(var_or_const, Constant)
+                and var.concretetype != lltype.Void):
+                value = var_or_const.value
+                value = lltype._cast_whatever(var.concretetype, value)
+                renamings_constants[var] = Constant(value, var.concretetype)
         #
         for op in block.operations:
             if renamings_constants:

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py	Sat May 22 13:27:31 2010
@@ -241,7 +241,7 @@
 
     def build_ll_0_alloc_with_del(RESULT, vtable):
         def _ll_0_alloc_with_del():
-            p = lltype.malloc(RESULT)
+            p = lltype.malloc(RESULT.TO)
             lltype.cast_pointer(rclass.OBJECTPTR, p).typeptr = vtable
             return p
         return _ll_0_alloc_with_del

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py	Sat May 22 13:27:31 2010
@@ -22,7 +22,6 @@
 from pypy.rlib.jit import DEBUG_OFF, DEBUG_PROFILE, DEBUG_STEPS, DEBUG_DETAILED
 from pypy.jit.metainterp.compile import GiveUp
 from pypy.jit.codewriter.jitcode import JitCode, SwitchDictDescr
-from pypy.jit.codewriter import effectinfo as ef
 
 # ____________________________________________________________
 
@@ -1037,8 +1036,8 @@
     def do_residual_call(self, funcbox, descr, argboxes):
         allboxes = [funcbox] + argboxes
         effectinfo = descr.get_extra_info()
-        if (effectinfo is None or
-            effectinfo.extraeffect == ef.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE):
+        if (effectinfo is None or effectinfo.extraeffect ==
+                                effectinfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE):
             # residual calls require attention to keep virtualizables in-sync
             self.metainterp.vable_and_vrefs_before_residual_call()
             # xxx do something about code duplication
@@ -1054,11 +1053,11 @@
                 return self.metainterp.assert_no_exception()
         else:
             effect = effectinfo.extraeffect
-            if effect == ef.EF_CANNOT_RAISE:
+            if effect == effectinfo.EF_CANNOT_RAISE:
                 opnum, exc = rop.CALL, False
-            elif effect == ef.EF_PURE:
+            elif effect == effectinfo.EF_PURE:
                 opnum, exc = rop.CALL_PURE, False
-            elif effect == ef.EF_LOOPINVARIANT:
+            elif effect == effectinfo.EF_LOOPINVARIANT:
                 opnum, exc = rop.CALL_LOOPINVARIANT, True
             else:
                 opnum, exc = rop.CALL, True

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_compile.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_compile.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_compile.py	Sat May 22 13:27:31 2010
@@ -2,7 +2,8 @@
 from pypy.jit.metainterp.history import BoxInt
 from pypy.jit.metainterp.specnode import NotSpecNode, ConstantSpecNode
 from pypy.jit.metainterp.compile import insert_loop_token, compile_new_loop
-from pypy.jit.metainterp.compile import ResumeGuardDescr, ResumeGuardCounters
+from pypy.jit.metainterp.compile import ResumeGuardDescr
+from pypy.jit.metainterp.compile import ResumeGuardCountersInt
 from pypy.jit.metainterp import optimize, jitprof, typesystem
 from pypy.jit.metainterp.test.oparser import parse
 from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin
@@ -107,49 +108,49 @@
 
 
 def test_resume_guard_counters():
-    rgc = ResumeGuardCounters()
+    rgc = ResumeGuardCountersInt()
     # fill in the table
     for i in range(5):
-        count = rgc.see(BoxInt(100+i))
+        count = rgc.see_int(100+i)
         assert count == 1
-        count = rgc.see(BoxInt(100+i))
+        count = rgc.see_int(100+i)
         assert count == 2
         assert rgc.counters == [0] * (4-i) + [2] * (1+i)
     for i in range(5):
-        count = rgc.see(BoxInt(100+i))
+        count = rgc.see_int(100+i)
         assert count == 3
     # make a distribution:  [5, 4, 7, 6, 3]
     assert rgc.counters == [3, 3, 3, 3, 3]
-    count = rgc.see(BoxInt(101))
+    count = rgc.see_int(101)
     assert count == 4
-    count = rgc.see(BoxInt(101))
+    count = rgc.see_int(101)
     assert count == 5
-    count = rgc.see(BoxInt(101))
+    count = rgc.see_int(101)
     assert count == 6
-    count = rgc.see(BoxInt(102))
+    count = rgc.see_int(102)
     assert count == 4
-    count = rgc.see(BoxInt(102))
+    count = rgc.see_int(102)
     assert count == 5
-    count = rgc.see(BoxInt(102))
+    count = rgc.see_int(102)
     assert count == 6
-    count = rgc.see(BoxInt(102))
+    count = rgc.see_int(102)
     assert count == 7
-    count = rgc.see(BoxInt(103))
+    count = rgc.see_int(103)
     assert count == 4
-    count = rgc.see(BoxInt(104))
+    count = rgc.see_int(104)
     assert count == 4
-    count = rgc.see(BoxInt(104))
+    count = rgc.see_int(104)
     assert count == 5
     assert rgc.counters == [5, 4, 7, 6, 3]
     # the next new item should throw away 104, as 5 is the middle counter
-    count = rgc.see(BoxInt(190))
+    count = rgc.see_int(190)
     assert count == 1
     assert rgc.counters == [1, 4, 7, 6, 3]
     # the next new item should throw away 103, as 4 is the middle counter
-    count = rgc.see(BoxInt(191))
+    count = rgc.see_int(191)
     assert count == 1
     assert rgc.counters == [1, 1, 7, 6, 3]
     # the next new item should throw away 100, as 3 is the middle counter
-    count = rgc.see(BoxInt(192))
+    count = rgc.see_int(192)
     assert count == 1
     assert rgc.counters == [1, 1, 7, 6, 1]

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_optimizefindnode.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_optimizefindnode.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_optimizefindnode.py	Sat May 22 13:27:31 2010
@@ -6,7 +6,7 @@
 
 from pypy.jit.backend.llgraph import runner
 from pypy.jit.metainterp.history import (BoxInt, BoxPtr, ConstInt, ConstPtr,
-                                         Const, ConstAddr, TreeLoop, BoxObj,
+                                         Const, TreeLoop, BoxObj,
                                          ConstObj, AbstractDescr)
 from pypy.jit.metainterp.optimizefindnode import PerfectSpecializationFinder
 from pypy.jit.metainterp.optimizefindnode import BridgeSpecializationFinder
@@ -16,7 +16,7 @@
 from pypy.jit.metainterp.specnode import VirtualArraySpecNode
 from pypy.jit.metainterp.specnode import VirtualStructSpecNode
 from pypy.jit.metainterp.specnode import ConstantSpecNode
-from pypy.jit.metainterp.effectinfo import EffectInfo
+from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.metainterp.test.oparser import parse
 
 def test_sort_descrs():
@@ -113,7 +113,7 @@
                                  EffectInfo([adescr], [], []))
     mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                  EffectInfo([nextdescr], [], [],
-                            forces_virtual_or_virtualizable=True))
+                            EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE))
     class LoopToken(AbstractDescr):
         pass
     asmdescr = LoopToken() # it can be whatever, it's not a descr though
@@ -129,83 +129,83 @@
     jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable
     jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable)
 
-    cpu.class_sizes = {
-        cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE),
-        cpu.cast_adr_to_int(node_vtable_adr2): cpu.sizeof(NODE2),
-        cpu.cast_adr_to_int(u_vtable_adr): cpu.sizeof(U),
-        cpu.cast_adr_to_int(jvr_vtable_adr): cpu.sizeof(
-                                                   vrefinfo.JIT_VIRTUAL_REF),
-        }
+##    cpu.class_sizes = {
+##        llmemory.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE),
+##        llmemory.cast_adr_to_int(node_vtable_adr2): cpu.sizeof(NODE2),
+##        llmemory.cast_adr_to_int(u_vtable_adr): cpu.sizeof(U),
+##        llmemory.cast_adr_to_int(jvr_vtable_adr): cpu.sizeof(
+##                                                   vrefinfo.JIT_VIRTUAL_REF),
+##        }
     namespace = locals()
 
-class OOtypeMixin(object):
+class OOtypeMixin_xxx_disabled(object):
     type_system = 'ootype'
 
-    def get_class_of_box(self, box):
-        root = box.getref(ootype.ROOT)
-        return ootype.classof(root)
+##    def get_class_of_box(self, box):
+##        root = box.getref(ootype.ROOT)
+##        return ootype.classof(root)
     
-    cpu = runner.OOtypeCPU(None)
-    NODE = ootype.Instance('NODE', ootype.ROOT, {})
-    NODE._add_fields({'value': ootype.Signed,
-                      'floatval' : ootype.Float,
-                      'next': NODE})
-    NODE2 = ootype.Instance('NODE2', NODE, {'other': NODE})
-
-    node_vtable = ootype.runtimeClass(NODE)
-    node_vtable_adr = ootype.cast_to_object(node_vtable)
-    node_vtable2 = ootype.runtimeClass(NODE2)
-    node_vtable_adr2 = ootype.cast_to_object(node_vtable2)
-
-    node = ootype.new(NODE)
-    nodebox = BoxObj(ootype.cast_to_object(node))
-    myptr = nodebox.value
-    myptr2 = ootype.cast_to_object(ootype.new(NODE))
-    nodebox2 = BoxObj(ootype.cast_to_object(node))
-    valuedescr = cpu.fielddescrof(NODE, 'value')
-    floatdescr = cpu.fielddescrof(NODE, 'floatval')
-    nextdescr = cpu.fielddescrof(NODE, 'next')
-    otherdescr = cpu.fielddescrof(NODE2, 'other')
-    nodesize = cpu.typedescrof(NODE)
-    nodesize2 = cpu.typedescrof(NODE2)
-
-    arraydescr = cpu.arraydescrof(ootype.Array(ootype.Signed))
-    floatarraydescr = cpu.arraydescrof(ootype.Array(ootype.Float))
-
-    # a plain Record
-    S = ootype.Record({'a': ootype.Signed, 'b': NODE})
-    ssize = cpu.typedescrof(S)
-    adescr = cpu.fielddescrof(S, 'a')
-    bdescr = cpu.fielddescrof(S, 'b')
-    sbox = BoxObj(ootype.cast_to_object(ootype.new(S)))
-    arraydescr2 = cpu.arraydescrof(ootype.Array(S))
-
-    T = ootype.Record({'c': ootype.Signed,
-                       'd': ootype.Array(NODE)})
-    tsize = cpu.typedescrof(T)
-    cdescr = cpu.fielddescrof(T, 'c')
-    ddescr = cpu.fielddescrof(T, 'd')
-    arraydescr3 = cpu.arraydescrof(ootype.Array(NODE))
-
-    U = ootype.Instance('U', ootype.ROOT, {'one': ootype.Array(NODE)})
-    usize = cpu.typedescrof(U)
-    onedescr = cpu.fielddescrof(U, 'one')
-    u_vtable = ootype.runtimeClass(U)
-    u_vtable_adr = ootype.cast_to_object(u_vtable)
-
-    # force a consistent order
-    valuedescr.sort_key()
-    nextdescr.sort_key()
-    adescr.sort_key()
-    bdescr.sort_key()
-
-    FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
-    nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT) # XXX fix ootype
-
-    cpu.class_sizes = {node_vtable_adr: cpu.typedescrof(NODE),
-                       node_vtable_adr2: cpu.typedescrof(NODE2),
-                       u_vtable_adr: cpu.typedescrof(U)}
-    namespace = locals()
+##    cpu = runner.OOtypeCPU(None)
+##    NODE = ootype.Instance('NODE', ootype.ROOT, {})
+##    NODE._add_fields({'value': ootype.Signed,
+##                      'floatval' : ootype.Float,
+##                      'next': NODE})
+##    NODE2 = ootype.Instance('NODE2', NODE, {'other': NODE})
+
+##    node_vtable = ootype.runtimeClass(NODE)
+##    node_vtable_adr = ootype.cast_to_object(node_vtable)
+##    node_vtable2 = ootype.runtimeClass(NODE2)
+##    node_vtable_adr2 = ootype.cast_to_object(node_vtable2)
+
+##    node = ootype.new(NODE)
+##    nodebox = BoxObj(ootype.cast_to_object(node))
+##    myptr = nodebox.value
+##    myptr2 = ootype.cast_to_object(ootype.new(NODE))
+##    nodebox2 = BoxObj(ootype.cast_to_object(node))
+##    valuedescr = cpu.fielddescrof(NODE, 'value')
+##    floatdescr = cpu.fielddescrof(NODE, 'floatval')
+##    nextdescr = cpu.fielddescrof(NODE, 'next')
+##    otherdescr = cpu.fielddescrof(NODE2, 'other')
+##    nodesize = cpu.typedescrof(NODE)
+##    nodesize2 = cpu.typedescrof(NODE2)
+
+##    arraydescr = cpu.arraydescrof(ootype.Array(ootype.Signed))
+##    floatarraydescr = cpu.arraydescrof(ootype.Array(ootype.Float))
+
+##    # a plain Record
+##    S = ootype.Record({'a': ootype.Signed, 'b': NODE})
+##    ssize = cpu.typedescrof(S)
+##    adescr = cpu.fielddescrof(S, 'a')
+##    bdescr = cpu.fielddescrof(S, 'b')
+##    sbox = BoxObj(ootype.cast_to_object(ootype.new(S)))
+##    arraydescr2 = cpu.arraydescrof(ootype.Array(S))
+
+##    T = ootype.Record({'c': ootype.Signed,
+##                       'd': ootype.Array(NODE)})
+##    tsize = cpu.typedescrof(T)
+##    cdescr = cpu.fielddescrof(T, 'c')
+##    ddescr = cpu.fielddescrof(T, 'd')
+##    arraydescr3 = cpu.arraydescrof(ootype.Array(NODE))
+
+##    U = ootype.Instance('U', ootype.ROOT, {'one': ootype.Array(NODE)})
+##    usize = cpu.typedescrof(U)
+##    onedescr = cpu.fielddescrof(U, 'one')
+##    u_vtable = ootype.runtimeClass(U)
+##    u_vtable_adr = ootype.cast_to_object(u_vtable)
+
+##    # force a consistent order
+##    valuedescr.sort_key()
+##    nextdescr.sort_key()
+##    adescr.sort_key()
+##    bdescr.sort_key()
+
+##    FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
+##    nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT) # XXX fix ootype
+
+##    cpu.class_sizes = {node_vtable_adr: cpu.typedescrof(NODE),
+##                       node_vtable_adr2: cpu.typedescrof(NODE2),
+##                       u_vtable_adr: cpu.typedescrof(U)}
+##    namespace = locals()
 
 class BaseTest(object):
     invent_fail_descr = None
@@ -220,6 +220,7 @@
         #
         def constclass(cls_vtable):
             if self.type_system == 'lltype':
+                XXX
                 return ConstAddr(llmemory.cast_ptr_to_adr(cls_vtable),
                                  self.cpu)
             else:
@@ -1160,14 +1161,13 @@
 class TestLLtype(BaseTestOptimizeFindNode, LLtypeMixin):
     pass
 
-class TestOOtype(BaseTestOptimizeFindNode, OOtypeMixin):
-
-    def test_find_nodes_instanceof(self):
-        ops = """
-        [i0]
-        p0 = new_with_vtable(ConstClass(node_vtable))
-        i1 = instanceof(p0, descr=nodesize)
-        jump(i1)
-        """
-        boxes, getnode = self.find_nodes(ops, 'Not')
-        assert not getnode(boxes.p0).escaped
+##class TestOOtype(BaseTestOptimizeFindNode, OOtypeMixin):
+##    def test_find_nodes_instanceof(self):
+##        ops = """
+##        [i0]
+##        p0 = new_with_vtable(ConstClass(node_vtable))
+##        i1 = instanceof(p0, descr=nodesize)
+##        jump(i1)
+##        """
+##        boxes, getnode = self.find_nodes(ops, 'Not')
+##        assert not getnode(boxes.p0).escaped



More information about the Pypy-commit mailing list