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

cfbolz at codespeak.net cfbolz at codespeak.net
Thu Jan 12 00:04:03 CET 2006


Author: cfbolz
Date: Thu Jan 12 00:04:01 2006
New Revision: 22000

Modified:
   pypy/dist/pypy/translator/backendopt/escape.py
   pypy/dist/pypy/translator/backendopt/test/test_escape.py
Log:
some small fixes to the adi. is now able to treat the whole rpystone - not sure
whether it produces useful info.


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 00:04:01 2006
@@ -77,6 +77,7 @@
         self.constant_cps = {} # const: creationpoint
         self.dependencies = {} # creationpoint: {block: graph containing it}
         self.functionargs = {} # graph: list of state of args
+        self.flown_blocks = {} # block: True
     
     def getstate(self, var_or_const):
         if not isonheap(var_or_const):
@@ -129,6 +130,7 @@
 
     def flow_block(self, block, graph):
         print "flowing in block %s of function %s" % (block, graph.name)
+        self.flown_blocks[block] = True
         if block is graph.returnblock:
             if isonheap(block.inputargs[0]):
                 changed = self.getstate(block.inputargs[0]).setescapes()
@@ -139,7 +141,7 @@
                 changed = self.getstate(block.inputargs[0]).setescapes()
                 self.handle_changed(changed)
             if isonheap(block.inputargs[0]):
-                changed = self.gestate(block.inputargs[1]).setescapes()
+                changed = self.getstate(block.inputargs[1]).setescapes()
                 self.handle_changed(changed)
             return
         self.curr_block = block
@@ -154,7 +156,9 @@
             targetargs = self.getstates(exit.target.inputargs)
             print "   newargs", args
             print "   targetargs", targetargs
-            if multicontains(targetargs, args):
+            # flow every block at least once:
+            if (multicontains(targetargs, args) and
+                exit.target in self.flown_blocks):
                 print "   not necessary"
                 continue
             else:
@@ -203,6 +207,7 @@
 
     def register_state_dependency(self, state1, state2):
         "state1 depends on state2: if state2 does escape/change, so does state1"
+        # change state1 according to how state2 is now
         escapes = state2.does_escape()
         if escapes and not state1.does_escape():
             changed = state1.setescapes()
@@ -211,19 +216,26 @@
         if changes and not state1:
             changed = state1.setchanges()
             self.handle_changed(changed)
+        # register a dependency of the current block on state2:
+        # that means that if state2 changes the current block will be reflown
+        # triggering this function again and thus updating state1
         self.register_block_dependency(state2)
 
     # _____________________________________________________________________
     # operation implementations
 
-    def malloc(self, op, type):
+    def malloc(self, op, typestate):
         return VarState(self.get_creationpoint(op.result, "malloc"))
 
+    def malloc_varsize(self, op, typestate, lengthstate):
+        return VarState(self.get_creationpoint(op.result, "malloc_varsize"))
+
     def cast_pointer(self, op, state):
         return state
     
     def setfield(self, op, objstate, fieldname, valuestate):
         changed = objstate.setchanges()
+        self.handle_changed(changed)
         if valuestate is not None:
             # be pessimistic for now:
             # everything that gets stored into a structure escapes and changes
@@ -233,15 +245,46 @@
             changed = valuestate.setescapes()
             self.handle_changed(changed)
         return None
+
+    def setarrayitem(self, op, objstate, indexstate, valuestate):
+        changed = objstate.setchanges()
+        self.handle_changed(changed)
+        if valuestate is not None:
+            # everything that gets stored into a structure escapes and changes
+            self.handle_changed(changed)
+            changed = valuestate.setchanges()
+            self.handle_changed(changed)
+            changed = valuestate.setescapes()
+            self.handle_changed(changed)
+        return None
+
+    def getarrayitem(self, op, objstate, indexstate):
+        if isonheap(op.result):
+            return VarState(self.get_creationpoint(op.result, "getarrayitem"))
     
     def getfield(self, op, objstate, fieldname):
         if isonheap(op.result):
             # assume that getfield creates a new value
             return VarState(self.get_creationpoint(op.result, "getfield"))
 
+    def getsubstruct(self, op, objstate, fieldname):
+        # since this is really an embedded struct, it has the same
+        # state, the same creationpoints, etc.
+        return objstate
+
+    def getarraysize(self, op, arraystate):
+        pass
+
     def direct_call(self, op, function, *args):
         graph = get_graph(op.args[0], self.translation_context)
-        result, funcargs = self.schedule_function(graph)
+        if graph is None:
+            if len(filter(None, args)):
+                raise NotImplementedError, "can't handle call %s" % (op, )
+            else:
+                result = None
+                funcargs = [None] * len(args)
+        else:
+            result, funcargs = self.schedule_function(graph)
         assert len(args) == len(funcargs)
         for localarg, funcarg in zip(args, funcargs):
             if localarg is None:
@@ -267,8 +310,15 @@
             # assume that a call creates a new value
             return VarState(self.get_creationpoint(op.result, "indirect_call"))
 
-    def ptr_iszero(self, op, ptr):
+    def ptr_iszero(self, op, ptrstate):
         return None
+
+    cast_ptr_to_int = ptr_iszero
+
+    def same_as(self, op, objstate):
+        return objstate
+
+    
  
 def isonheap(var_or_const):
     return isinstance(var_or_const.concretetype, lltype.Ptr)

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 00:04:01 2006
@@ -245,3 +245,55 @@
     a2crep = a2state.creation_points.keys()[0]
     assert a1crep.changes and a2crep.changes
     assert not a1crep.escapes and a2crep.escapes
+
+def test_getarray():
+    class A(object):
+        pass
+    def f():
+        a = A()
+        l = [None]
+        l[0] = a
+    t, adi, graph = build_adi(f, [])
+    avar = graph.startblock.operations[0].result
+    state = adi.getstate(avar)
+    assert len(state.creation_points) == 1
+    crep = state.creation_points.keys()[0]
+    assert crep.changes
+    assert crep.escapes
+
+def test_flow_blocksonce():
+    class A(object):
+        pass
+    def f():
+        a = 0
+        for i in range(10):
+            a += i
+        b = A()
+        b.x = 1
+        return b.x + 2
+    t, adi, graph = build_adi(f, [])
+    avar = graph.startblock.exits[0].target.exits[1].target.operations[0].result
+    state = adi.getstate(avar)
+    assert not state.does_escape()
+
+def test_call_external():
+    import time
+    def f():
+        return time.time()
+    #does not crash
+    t, adi, graph = build_adi(f, [])
+
+def test_getsubstruct():
+    def f(i):
+        s = "hello"
+        return s[i]
+    # does not crash
+    t, adi, graph = build_adi(f, [int])
+
+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])
+
+    



More information about the Pypy-commit mailing list