[pypy-svn] r32486 - in pypy/branch/kill-keepalives/pypy: rpython/lltypesystem rpython/memory translator/backendopt

mwh at codespeak.net mwh at codespeak.net
Tue Sep 19 13:22:39 CEST 2006


Author: mwh
Date: Tue Sep 19 13:22:38 2006
New Revision: 32486

Modified:
   pypy/branch/kill-keepalives/pypy/rpython/lltypesystem/lloperation.py
   pypy/branch/kill-keepalives/pypy/rpython/memory/gctransform.py
   pypy/branch/kill-keepalives/pypy/translator/backendopt/malloc.py
Log:
attempt number #12214321 at climbing out of the rctypes hole.
this one adds a local_raw_malloc operation and a step in the gctransformer to
get rid of them again.  doesn't work, checking in to get onto a local machine
and use --view.


Modified: pypy/branch/kill-keepalives/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/kill-keepalives/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/branch/kill-keepalives/pypy/rpython/lltypesystem/lloperation.py	Tue Sep 19 13:22:38 2006
@@ -329,6 +329,7 @@
     # __________ address operations __________
 
     'raw_malloc':           LLOp(canraise=(MemoryError,)),
+    'local_raw_malloc':     LLOp(canraise=(MemoryError,)),
     'raw_malloc_usage':     LLOp(sideeffects=False),
     'raw_free':             LLOp(),
     'raw_memclear':         LLOp(),

Modified: pypy/branch/kill-keepalives/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/branch/kill-keepalives/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/branch/kill-keepalives/pypy/rpython/memory/gctransform.py	Tue Sep 19 13:22:38 2006
@@ -3,7 +3,7 @@
 from pypy.rpython.lltypesystem.lloperation import llop, LL_OPERATIONS
 from pypy.objspace.flow.model import SpaceOperation, Variable, Constant, \
      c_last_exception, FunctionGraph, Block, Link, checkgraph
-from pypy.translator.unsimplify import varoftype
+from pypy.translator.unsimplify import varoftype, copyvar
 from pypy.translator.unsimplify import insert_empty_block
 from pypy.translator.unsimplify import insert_empty_startblock
 from pypy.translator.unsimplify import starts_with_empty_block
@@ -81,6 +81,7 @@
             return
         self.seen_graphs[graph] = True
         self.links_to_split = {} # link -> vars to pop_alive across the link
+        self.seen_local_raw_malloc = False
 
         # for sanity, we need an empty block at the start of the graph
         if not starts_with_empty_block(graph):
@@ -107,12 +108,66 @@
         if starts_with_empty_block(graph):
             remove_empty_startblock(graph)
 
+        if self.seen_local_raw_malloc:
+            self.remove_local_mallocs(graph)
+
         self.links_to_split = None
         v = Variable('vanishing_exc_value')
         v.concretetype = self.get_lltype_of_exception_value()
         graph.exc_cleanup = (v, self.pop_alive(v))
         return is_borrowed    # xxx for tests only
 
+    def remove_local_mallocs(self, graph):
+        from pypy.translator.backendopt.malloc import compute_lifetimes
+        lifetimes = compute_lifetimes(graph)
+        for info in lifetimes:
+            cand = True
+            # XXX do checking
+            for cp in info.creationpoints:
+                if cp[0] != "op":
+                    cand = False
+                    break
+                op = cp[2]
+                if op.opname != 'local_raw_malloc':
+                    cand = False
+                    break
+                op.opname = 'raw_malloc'
+            if cand:
+                for cp in info.creationpoints:
+                    cp[2].opname = 'raw_malloc'
+
+                variables_by_block = {}
+                for block, var in info.variables:
+                    vars = variables_by_block.setdefault(block, {})
+                    vars[var] = True
+                for block, vars in variables_by_block.iteritems():
+                    links_with_a_var = []
+                    links_without_a_var = []
+                    for link in block.exits:
+                        if set(vars) ^ set(link.args):
+                            links_with_a_var.append(link)
+                        else:
+                            links_without_a_var.append(link)
+                    #if not links_without_a_var:
+                    #    continue
+                    for link in links_without_a_var:
+                        for v in vars:
+                            if v.concretetype == llmemory.Address:
+                                break
+                        newblock = insert_empty_block(None, link)
+                        link.args.append(v)
+                        newblock.inputargs.append(copyvar(None, v))
+                        if v.concretetype != llmemory.Address:
+                            newv = varoftype(llmemory.Address)
+                            newblock.operations.append(SpaceOperation(
+                                "cast_ptr_to_adr", [newblock.inputargs[-1]], newv))
+                            v = newv
+                        else:
+                            v = newblock.inputargs[-1]
+                        newblock.operations.append(SpaceOperation(
+                            "raw_free", [v], varoftype(lltype.Void)))
+        checkgraph(graph)
+
     def compute_borrowed_vars(self, graph):
         # the input args are borrowed, and stay borrowed for as long as they
         # are not merged with other values.
@@ -271,6 +326,10 @@
     replace_setinteriorfield = replace_setfield
     replace_setarrayitem = replace_setfield
 
+    def replace_local_raw_malloc(self, op, livevars, block):
+        self.seen_local_raw_malloc = True
+        return [op]
+
     def replace_safe_call(self, op, livevars, block):
         return [SpaceOperation("direct_call", op.args, op.result)]
 

Modified: pypy/branch/kill-keepalives/pypy/translator/backendopt/malloc.py
==============================================================================
--- pypy/branch/kill-keepalives/pypy/translator/backendopt/malloc.py	(original)
+++ pypy/branch/kill-keepalives/pypy/translator/backendopt/malloc.py	Tue Sep 19 13:22:38 2006
@@ -341,6 +341,15 @@
                         S = op.args[0].concretetype.TO
                         fldnames = [a.value for a in op.args[1:-1]]
                         key = key_for_field_access(S, *fldnames)
+                        if len(fldnames) == 1 and fldnames[0] in fields_to_raw_free and not isinstance(op.args[2], Constant):
+                            # find the raw malloc and replace it with a local_raw_malloc
+                            # XXX delicate in the extreme!
+                            i = -1
+                            while newops[i].opname != 'raw_malloc':
+                                i -= 1
+                            newops[i] = SpaceOperation("local_raw_malloc",
+                                                       newops[i].args,
+                                                       newops[i].result)
                         assert key in newvarsmap
                         if key in accessed_substructs:
                             c_name = Constant('data', lltype.Void)
@@ -429,12 +438,12 @@
                         newargs.append(arg)
                 link.args[:] = newargs
 
-            if not var_exits:
-                for field in fields_to_raw_free:
-                    newops.append(SpaceOperation("flavored_free",
-                                                 [Constant("raw", lltype.Void),
-                                                  newvarsmap[key_for_field_access(STRUCT, field)]],
-                                                 varoftype(lltype.Void)))
+##             if not var_exits:
+##                 for field in fields_to_raw_free:
+##                     newops.append(SpaceOperation("flavored_free",
+##                                                  [Constant("raw", lltype.Void),
+##                                                   newvarsmap[key_for_field_access(STRUCT, field)]],
+##                                                  varoftype(lltype.Void)))
 
             if insert_keepalive and last_removed_access is not None:
                 keepalives = []



More information about the Pypy-commit mailing list