[pypy-svn] r23189 - in pypy/dist/pypy/rpython/memory: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Thu Feb 9 23:22:12 CET 2006


Author: cfbolz
Date: Thu Feb  9 23:22:11 2006
New Revision: 23189

Modified:
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/rpython/memory/test/test_gctransform.py
Log:
simple analysis to find out how many variables would need to be reread after a
call, if different strategies for finding ther roots would be used.


Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Thu Feb  9 23:22:11 2006
@@ -549,3 +549,52 @@
         self.finalizer_graphs[TYPE] = g
         return g
         
+# ___________________________________________________________________
+# calculate some statistics about the number of variables that need
+# to be cared for across a call
+
+relevant_ops = ["direct_call", "indirect_call", "malloc"]
+
+def relevant_gcvars_block(block):
+    import sets
+    result = []
+    def filter_ptr(args):
+        return [arg for arg in args if isinstance(arg.concretetype, lltype.Ptr)]
+    def live_vars_before(index):
+        if index == 0:
+            return sets.Set(filter_ptr(block.inputargs))
+        op = block.operations[index - 1]
+        result = live_vars_before(index - 1).union(filter_ptr(op.args + [op.result]))
+        return result
+    def live_vars_after(index):
+        if index == len(block.operations) - 1:
+            result = sets.Set()
+            for exit in block.exits:
+                result = result.union(filter_ptr(exit.args))
+            return result
+        op = block.operations[index + 1]
+        result = live_vars_after(index + 1).union(filter_ptr(op.args + [op.result]))
+        
+        return result
+    for i, op in enumerate(block.operations):
+        if op.opname not in relevant_ops:
+            continue
+        print op,
+        live_before = live_vars_before(i)
+        live_after = live_vars_after(i)
+        print live_before, live_after
+        result.append(len(live_before.intersection(live_after)))
+    return result
+
+def relevant_gcvars_graph(graph):
+    result = []
+    for block in graph.iterblocks():
+        result += relevant_gcvars_block(block)
+    return result
+
+def relevant_gcvars(t):
+    result = []
+    for graph in t.graphs:
+        result.extend(relevant_gcvars_graph(graph))
+    return result
+

Modified: pypy/dist/pypy/rpython/memory/test/test_gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/test/test_gctransform.py	Thu Feb  9 23:22:11 2006
@@ -1,6 +1,6 @@
 from pypy.rpython.memory import gctransform
 from pypy.objspace.flow.model import c_last_exception, Variable
-from pypy.rpython.memory.gctransform import var_needsgc, var_ispyobj
+from pypy.rpython.memory.gctransform import var_needsgc, var_ispyobj, relevant_gcvars_graph, relevant_gcvars
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.rpython.lltypesystem import lltype
 from pypy.objspace.flow.model import Variable
@@ -48,11 +48,15 @@
             ops.setdefault(op.opname, []).append(op)
     return ops
 
-def rtype_and_transform(func, inputtypes, transformcls, specialize=True, check=True):
+def rtype(func, inputtypes, specialize=True):
     t = TranslationContext()
     t.buildannotator().build_types(func, inputtypes)
     if specialize:
         t.buildrtyper().specialize(t)
+    return t    
+
+def rtype_and_transform(func, inputtypes, transformcls, specialize=True, check=True):
+    t = rtype(func, inputtypes, specialize)
     transformer = transformcls(t)
     transformer.transform(t.graphs)
     if conftest.option.view:
@@ -448,6 +452,7 @@
         s1.x = s2
     t, transformer = rtype_and_transform(f, [], gctransform.RefcountingGCTransformer, check=False)
 
+
 def test_boehm_finalizer_simple():
     S = lltype.GcStruct("S", ('x', lltype.Signed))
     f, t = make_boehm_finalizer(S)
@@ -493,3 +498,28 @@
     pinf = lltype.attachRuntimeTypeInfo(S, qp, destrptr=dp)
     py.test.raises(Exception, "make_boehm_finalizer(S)")
 
+# ______________________________________________________________________
+# test statistics
+
+def test_count_vars_simple():
+    S = lltype.GcStruct('abc', ('x', lltype.Signed))
+    def f():
+        s1 = lltype.malloc(S)
+        s2 = lltype.malloc(S)
+        s1.x = 1
+        s2.x = 2
+        return s1.x + s2.x
+    t = rtype(f, [])
+    assert relevant_gcvars_graph(graphof(t, f)) == [0, 1]
+
+def test_count_vars_big():
+    from pypy.translator.goal.targetrpystonex import make_target_definition
+    from pypy.translator.backendopt.all import backend_optimizations
+    entrypoint, _, _ = make_target_definition(10)
+    t = rtype(entrypoint, [int])
+    backend_optimizations(t)
+    # does not crash
+    rel = relevant_gcvars(t)
+    print rel
+    print sum(rel) / float(len(rel)), max(rel), min(rel)
+



More information about the Pypy-commit mailing list