# [pypy-svn] r32884 - in pypy/dist/pypy/rpython/memory/gctransform2: . test

mwh at codespeak.net mwh at codespeak.net
Wed Oct 4 19:32:35 CEST 2006

```Author: mwh
Date: Wed Oct  4 19:32:34 2006
New Revision: 32884

pypy/dist/pypy/rpython/memory/gctransform2/statistics.py   (contents, props changed)
pypy/dist/pypy/rpython/memory/gctransform2/test/test_statistics.py   (contents, props changed)
Log:
onto the odd and possibly-dead stuff: statistics gathering code

==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/memory/gctransform2/statistics.py	Wed Oct  4 19:32:34 2006
@@ -0,0 +1,55 @@
+# calculate some statistics about the number of variables that need
+# to be cared for across a call
+
+from pypy.rpython.lltypesystem import lltype, llmemory
+
+
+relevant_ops = ["direct_call", "indirect_call", "malloc", "malloc_varsize"]
+
+def filter_for_ptr(arg):
+    return isinstance(arg.concretetype, lltype.Ptr)
+
+def filter_for_nongcptr(arg):
+    return isinstance(arg.concretetype, lltype.Ptr) and not arg.concretetype._needsgc()
+
+def relevant_gcvars_block(block, filter=filter_for_ptr):
+    import sets
+    result = []
+    def filter_ptr(args):
+        return [arg for arg in args if filter(arg)]
+    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
+        live_before = live_vars_before(i)
+        live_after = live_vars_after(i)
+        result.append(len(live_before.intersection(live_after)))
+    return result
+
+def relevant_gcvars_graph(graph, filter=filter_for_ptr):
+    result = []
+    for block in graph.iterblocks():
+        result += relevant_gcvars_block(block, filter)
+    return result
+
+def relevant_gcvars(t, filter=filter_for_ptr):
+    result = []
+    for graph in t.graphs:
+        result.extend(relevant_gcvars_graph(graph, filter))
+    return result
+

==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/memory/gctransform2/test/test_statistics.py	Wed Oct  4 19:32:34 2006
@@ -0,0 +1,32 @@
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.memory.gctransform2.test.test_transform import \
+     rtype
+from pypy.rpython.memory.gctransform2.statistics import \
+     relevant_gcvars_graph, relevant_gcvars, filter_for_nongcptr
+from pypy.translator.translator import graphof
+
+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)
+
+    rel = relevant_gcvars(t, filter_for_nongcptr)
+    print rel
+    print sum(rel) / float(len(rel)), max(rel), min(rel)

```