[pypy-svn] r25457 - in pypy/dist/pypy: rpython/memory translator/backendopt translator/backendopt/test

cfbolz at codespeak.net cfbolz at codespeak.net
Thu Apr 6 18:09:19 CEST 2006


Author: cfbolz
Date: Thu Apr  6 18:09:17 2006
New Revision: 25457

Modified:
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/translator/backendopt/inline.py
   pypy/dist/pypy/translator/backendopt/support.py
   pypy/dist/pypy/translator/backendopt/test/test_inline.py
Log:
(pedronis, cfbolz):

fix the insertion of keepalive in the non-exceptional case. make the skipped
test pass


Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Thu Apr  6 18:09:17 2006
@@ -5,6 +5,7 @@
      c_last_exception, FunctionGraph, Block, Link, checkgraph
 from pypy.translator.unsimplify import insert_empty_block
 from pypy.translator.translator import graphof
+from pypy.translator.backendopt.support import var_needsgc, needs_conservative_livevar_calculation
 from pypy.annotation import model as annmodel
 from pypy.rpython import rmodel, rptr, annlowlevel
 from pypy.rpython.memory import gc, lladdress
@@ -13,13 +14,6 @@
 
 NEVER_RAISING_OPS = ['gc_protect', 'gc_unprotect']
 
-def var_needsgc(var):
-    if hasattr(var, 'concretetype'):
-        vartype = var.concretetype
-        return isinstance(vartype, lltype.Ptr) and vartype._needsgc()
-    else:
-        # assume PyObjPtr
-        return True
 
 def var_ispyobj(var):
     if hasattr(var, 'concretetype'):
@@ -652,18 +646,6 @@
                 for a in gc_pointers_inside(v.items[i], adr + llmemory.itemoffsetof(t, i)):
                     yield a
 
-def needs_conservative_livevar_calculation(block):
-    from pypy.rpython.lltypesystem import rclass
-    vars = block.getvariables()
-    for var in vars:
-        TYPE = getattr(var, "concretetype", lltype.Ptr(lltype.PyObject))
-        if isinstance(TYPE, lltype.Ptr) and not var_needsgc(var):
-            try:
-                lltype.castable(TYPE, rclass.CLASSTYPE)
-            except lltype.InvalidCast:
-                return True
-    else:
-        return False
 
 class FrameworkGCTransformer(BoehmGCTransformer):
 

Modified: pypy/dist/pypy/translator/backendopt/inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/inline.py	(original)
+++ pypy/dist/pypy/translator/backendopt/inline.py	Thu Apr  6 18:09:17 2006
@@ -9,7 +9,7 @@
 from pypy.rpython.lltypesystem.lltype import Bool, typeOf, Void
 from pypy.rpython import rmodel
 from pypy.tool.algo import sparsemat
-from pypy.translator.backendopt.support import log
+from pypy.translator.backendopt.support import log, needs_conservative_livevar_calculation, var_needsgc
 
 BASE_INLINE_THRESHOLD = 32.4    # just enough to inline add__Int_Int()
 # and just small enough to prevend inlining of some rlist functions.
@@ -351,6 +351,24 @@
       
     def do_inline(self, block, index_operation):
         afterblock = split_block(self.translator, self.graph, block, index_operation)
+        conservative_keepalives = needs_conservative_livevar_calculation(block)
+        if conservative_keepalives:
+            keep_alive_vars = [var for var in block.getvariables()
+                                   if var_needsgc(var)]
+            # XXX you could maybe remove more, if the variables are kept
+            # alive by something else. but this is sometimes hard to know
+            for i, var in enumerate(keep_alive_vars):
+                try:
+                    index = block.exits[0].args.index(var)
+                    newvar = afterblock.inputargs[index]
+                except ValueError:
+                    block.exits[0].args.append(var)
+                    newvar = copyvar(self.translator, var)
+                    afterblock.inputargs.append(newvar)
+                keep_alive_vars[i] = newvar
+        else:
+            keep_alive_vars = [var for var in afterblock.operations[0].args
+                                   if var_needsgc(var)]
         # these variables have to be passed along all the links in the inlined
         # graph because the original function needs them in the blocks after
         # the inlined function
@@ -377,7 +395,7 @@
         linktoinlined.target = copiedstartblock
         linktoinlined.args = passon_args
         afterblock.inputargs = [self.op.result] + afterblock.inputargs
-        afterblock.operations = self.generate_keepalive(afterblock.inputargs) + afterblock.operations[1:]
+        afterblock.operations = afterblock.operations[1:]
         if self.graph_to_inline.returnblock in self.entrymap:
             self.rewire_returnblock(afterblock) 
         if self.graph_to_inline.exceptblock in self.entrymap:
@@ -386,6 +404,7 @@
             assert afterblock.exits[0].exitcase is None
             afterblock.exits = [afterblock.exits[0]]
             afterblock.exitswitch = None
+        afterblock.operations.extend(self.generate_keepalive(keep_alive_vars))
         self.search_for_calls(afterblock)
         self.search_for_calls(block)
 

Modified: pypy/dist/pypy/translator/backendopt/support.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/support.py	(original)
+++ pypy/dist/pypy/translator/backendopt/support.py	Thu Apr  6 18:09:17 2006
@@ -1,5 +1,5 @@
 import py
-from pypy.rpython.lltypesystem.lltype import functionptr, FuncType, typeOf
+from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.rmodel import inputconst 
 from pypy.tool.ansi_print import ansi_log
 
@@ -20,10 +20,31 @@
 def annotate(translator, func, result, args):
     args   = [arg.concretetype for arg in args]
     graph  = translator.rtyper.annotate_helper(func, args)
-    fptr   = functionptr(FuncType(args, result.concretetype), func.func_name, graph=graph)
-    c      = inputconst(typeOf(fptr), fptr) 
+    fptr   = lltype.functionptr(lltype.FuncType(args, result.concretetype), func.func_name, graph=graph)
+    c      = inputconst(lltype.typeOf(fptr), fptr) 
     return c
 
+def var_needsgc(var):
+    if hasattr(var, 'concretetype'):
+        vartype = var.concretetype
+        return isinstance(vartype, lltype.Ptr) and vartype._needsgc()
+    else:
+        # assume PyObjPtr
+        return True
+
+def needs_conservative_livevar_calculation(block):
+    from pypy.rpython.lltypesystem import rclass
+    vars = block.getvariables()
+    for var in vars:
+        TYPE = getattr(var, "concretetype", lltype.Ptr(lltype.PyObject))
+        if isinstance(TYPE, lltype.Ptr) and not var_needsgc(var):
+            try:
+                lltype.castable(TYPE, rclass.CLASSTYPE)
+            except lltype.InvalidCast:
+                return True
+    else:
+        return False
+
 def md5digest(translator):
     import md5
     m = md5.new()

Modified: pypy/dist/pypy/translator/backendopt/test/test_inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_inline.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_inline.py	Thu Apr  6 18:09:17 2006
@@ -435,7 +435,6 @@
     py.test.raises(CannotInline, check_inline, x3, x4, [])
 
 def test_keepalive_hard_case():
-    py.test.skip("fix this :(")
     from pypy.rpython.lltypesystem import lltype
     Y = lltype.Struct('y', ('n', lltype.Signed))
     X = lltype.GcStruct('x', ('y', Y))



More information about the Pypy-commit mailing list