[pypy-svn] r22082 - in pypy/dist/pypy/translator/backendopt: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Thu Jan 12 22:06:43 CET 2006


Author: cfbolz
Date: Thu Jan 12 22:06:42 2006
New Revision: 22082

Modified:
   pypy/dist/pypy/translator/backendopt/escape.py
   pypy/dist/pypy/translator/backendopt/test/test_escape.py
Log:
actually implement a transformation that removes puts structures on the stack -
not safe yet.


Modified: pypy/dist/pypy/translator/backendopt/escape.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/escape.py	(original)
+++ pypy/dist/pypy/translator/backendopt/escape.py	Thu Jan 12 22:06:42 2006
@@ -2,6 +2,7 @@
 from pypy.objspace.flow.model import Variable, Constant
 from pypy.rpython.lltypesystem import lltype
 from pypy.translator.simplify import get_graph
+from pypy.rpython.rmodel import inputconst
 
 class CreationPoint(object):
     def __init__(self, creation_method="?"):
@@ -147,6 +148,7 @@
         self.curr_block = block
         self.curr_graph = graph
         print "inputargs", self.getstates(block.inputargs)
+        
         for op in block.operations:
             self.flow_operation(op)
         print "checking exits..."
@@ -313,13 +315,14 @@
     def ptr_iszero(self, op, ptrstate):
         return None
 
-    cast_ptr_to_int = ptr_iszero
+    cast_ptr_to_int = keepalive = ptr_nonzero = ptr_iszero
+
+    def ptr_eq(self, op, ptr1state, ptr2state):
+        return None
 
     def same_as(self, op, objstate):
         return objstate
 
-    
- 
 def isonheap(var_or_const):
     return isinstance(var_or_const.concretetype, lltype.Ptr)
 
@@ -331,3 +334,20 @@
         elif not a.contains(b):
             return False
     return True
+
+def malloc_to_stack(t):
+    aib = AbstractDataFlowInterpreter(t)
+    for graph in t.graphs:
+        for block in graph.iterblocks():
+            for op in block.operations:
+                if op.opname == 'malloc':
+                    if graph.startblock not in aib.flown_blocks:
+                        aib.schedule_function(graph)
+                        aib.complete()
+                    varstate = aib.getstate(op.result)
+                    assert len(varstate.creation_points) == 1
+                    crep = varstate.creation_points.keys()[0]
+                    if not crep.escapes:
+                        print "moving object from heap to stack %s in %s" % (op, graph.name)
+                        op.opname = 'flavored_malloc'
+                        op.args.insert(0, inputconst(lltype.Void, 'stack'))

Modified: pypy/dist/pypy/translator/backendopt/test/test_escape.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_escape.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_escape.py	Thu Jan 12 22:06:42 2006
@@ -1,5 +1,6 @@
 from pypy.translator.translator import TranslationContext, graphof
-from pypy.translator.backendopt.escape import AbstractDataFlowInterpreter 
+from pypy.translator.backendopt.escape import AbstractDataFlowInterpreter, malloc_to_stack
+from pypy.rpython.llinterp import LLInterpreter
 
 def build_adi(function, types):
     t = TranslationContext()
@@ -11,6 +12,23 @@
     adi.complete()
     return t, adi, graph
 
+def check_malloc_removal(function, types, args, expected_result, must_remove=True):
+    t = TranslationContext()
+    t.buildannotator().build_types(function, types)
+    t.buildrtyper().specialize()
+    interp = LLInterpreter(t.rtyper)
+    graph = graphof(t, function)
+    res = interp.eval_graph(graph, args)
+    assert res == expected_result
+    malloc_to_stack(t)
+    if must_remove:
+        for block in graph.iterblocks():
+            for op in block.operations:
+                assert op.opname != "malloc"
+    res = interp.eval_graph(graph, args)
+    assert res == expected_result
+    return t
+
 def test_simple():
     class A(object):
         pass
@@ -64,7 +82,6 @@
     assert crep.changes
     assert not crep.escapes
     avarinloop = graph.startblock.exits[0].target.inputargs[1]
-    #t.view()
     state1 = adi.getstate(avarinloop)
     assert crep in state1.creation_points
     assert len(state1.creation_points) == 2
@@ -126,7 +143,6 @@
 def test_call():
     class A(object):
         pass
-    globala = A()
     def g(b):
         return b.i + 2
     def f():
@@ -290,10 +306,60 @@
     # does not crash
     t, adi, graph = build_adi(f, [int])
 
+def test_raise_escapes():
+    def f():
+        a = ValueError()
+        raise a
+    t, adi, graph = build_adi(f, [])
+    avar = graph.startblock.operations[0].result
+    state = adi.getstate(avar)
+    assert state.does_escape()
+    assert state.does_change()
+
+
 def test_big():
     from pypy.translator.goal.targetrpystonex import make_target_definition
     entrypoint, _, _ = make_target_definition(10)
     # does not crash
     t, adi, graph = build_adi(entrypoint, [int])
 
-    
+ 
+#__________________________________________________________
+# malloc removal tests
+
+def test_remove_simple():
+    class A(object):
+        pass
+    def f():
+        a = A()
+        a.x = 1
+        return a.x
+    check_malloc_removal(f, [], [], 1)
+
+def test_remove_aliasing():
+    class A:
+        pass
+    def fn6(n):
+        a1 = A()
+        a1.x = 5
+        a2 = A()
+        a2.x = 6
+        if n > 0:
+            a = a1
+        else:
+            a = a2
+        a.x = 12
+        return a1.x
+    t = check_malloc_removal(fn6, [int], [2], 12)
+
+def test_remove_call():
+    class A(object):
+        pass
+    def g(b):
+        return b.i + 2
+    def f():
+        a = A()
+        a.i = 2
+        return g(a)
+    t = check_malloc_removal(f, [], [], 4)
+



More information about the Pypy-commit mailing list