[pypy-svn] r25523 - in pypy/dist/pypy: doc/discussion rpython translator translator/backendopt translator/c/test

cfbolz at codespeak.net cfbolz at codespeak.net
Fri Apr 7 20:42:41 CEST 2006


Author: cfbolz
Date: Fri Apr  7 20:42:39 2006
New Revision: 25523

Modified:
   pypy/dist/pypy/doc/discussion/translation-swamp.txt
   pypy/dist/pypy/rpython/annlowlevel.py
   pypy/dist/pypy/rpython/typesystem.py
   pypy/dist/pypy/translator/backendopt/support.py
   pypy/dist/pypy/translator/c/test/test_typed.py
   pypy/dist/pypy/translator/driver.py
   pypy/dist/pypy/translator/interactive.py
   pypy/dist/pypy/translator/transform.py
Log:
(pedronis, cfbolz):

do the (very indeterministic) stack check insertion as late as possible, just
before code generation.


Modified: pypy/dist/pypy/doc/discussion/translation-swamp.txt
==============================================================================
--- pypy/dist/pypy/doc/discussion/translation-swamp.txt	(original)
+++ pypy/dist/pypy/doc/discussion/translation-swamp.txt	Fri Apr  7 20:42:39 2006
@@ -7,7 +7,7 @@
  
  * nondeterminism of insert stackcheck:
 
-    * move it after inlining
+    * (TESTING) move it after inlining
     * avoid inserting it multiple times in the same block
 
  * experiment with different heuristics:
@@ -24,4 +24,4 @@
  * move the inlining of gc helpers just before emitting the code.
    throw the graph away
 
- * for gcc: use just one implement file
+ * for gcc: use just one implement file (TESTING)

Modified: pypy/dist/pypy/rpython/annlowlevel.py
==============================================================================
--- pypy/dist/pypy/rpython/annlowlevel.py	(original)
+++ pypy/dist/pypy/rpython/annlowlevel.py	Fri Apr  7 20:42:39 2006
@@ -172,7 +172,7 @@
                                 "originally specified: %r\n"
                                 " found by annotating: %r" %
                                 (graph, s_result, s_real_result))
-        rtyper.type_system.perform_normalizations(rtyper, insert_stack_checks=False)
+        rtyper.type_system.perform_normalizations(rtyper)
         for r in self.delayedreprs:
             r.set_setup_delayed(False)
         for p, repr, obj in self.delayedconsts:

Modified: pypy/dist/pypy/rpython/typesystem.py
==============================================================================
--- pypy/dist/pypy/rpython/typesystem.py	(original)
+++ pypy/dist/pypy/rpython/typesystem.py	Fri Apr  7 20:42:39 2006
@@ -62,16 +62,12 @@
 in a graph."""
         raise NotImplementedError()
 
-    def perform_normalizations(self, rtyper, insert_stack_checks=True):
+    def perform_normalizations(self, rtyper):
         """Prepare the annotator's internal data structures for rtyping
         with the specified type system.
         """
         # default implementation
-        from pypy.translator.transform import insert_stackcheck
         from pypy.rpython.normalizecalls import perform_normalizations
-        # XXX stack checks cannot be inserted again
-        if insert_stack_checks:
-            insert_stackcheck(rtyper.annotator)
         perform_normalizations(rtyper)
 
 class LowLevelTypeSystem(TypeSystem):

Modified: pypy/dist/pypy/translator/backendopt/support.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/support.py	(original)
+++ pypy/dist/pypy/translator/backendopt/support.py	Fri Apr  7 20:42:39 2006
@@ -1,5 +1,6 @@
 import py
 from pypy.rpython.lltypesystem import lltype
+from pypy.translator.simplify import get_graph
 from pypy.rpython.rmodel import inputconst 
 from pypy.tool.ansi_print import ansi_log
 from pypy.translator.unsimplify import split_block, copyvar, insert_empty_block
@@ -94,6 +95,25 @@
         afterblock.operations.extend(generate_keepalive(keep_alive_vars))
     return afterblock
 
+def calculate_call_graph(translator):
+    calls = {}
+    for graph in translator.graphs:
+        if getattr(getattr(graph, "func", None), "suggested_primitive", False):
+            continue
+        calls[graph] = {}
+        for block in graph.iterblocks():
+            for op in block.operations:
+                if op.opname == "direct_call":
+                    called_graph = get_graph(op.args[0], translator)
+                    if called_graph is not None:
+                        calls[graph][called_graph] = block
+                if op.opname == "indirect_call":
+                    graphs = op.args[-1].value
+                    if graphs is not None:
+                        for called_graph in graphs:
+                            calls[graph][called_graph] = block
+    return calls
+
 def md5digest(translator):
     import md5
     m = md5.new()

Modified: pypy/dist/pypy/translator/c/test/test_typed.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_typed.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_typed.py	Fri Apr  7 20:42:39 2006
@@ -38,11 +38,13 @@
         return builder.get_entry_point()
 
     def getcompiled(self, func, view=False):
+        from pypy.translator.transform import insert_ll_stackcheck
         t = self.annotatefunc(func)
         self.process(t)
         if view or conftest.option.view:
             t.view()
         t.checkgraphs()
+        insert_ll_stackcheck(t)
         return self.compilefunc(t, func)
 
     def test_set_attr(self):
@@ -705,3 +707,18 @@
             return a1.check_list_is_true()
         fn = self.getcompiled(f)
         assert fn() == 1
+
+    def test_infinite_recursion(self):
+        def f(x):
+            if x:
+                return f(x)
+            return 1
+        def g(x=int):
+            try:
+                f(x)
+            except RuntimeError:
+                return 42
+            return 1
+        fn = self.getcompiled(g)
+        assert fn(0) == 1
+        assert fn(1) == 42

Modified: pypy/dist/pypy/translator/driver.py
==============================================================================
--- pypy/dist/pypy/translator/driver.py	(original)
+++ pypy/dist/pypy/translator/driver.py	Fri Apr  7 20:42:39 2006
@@ -205,6 +205,15 @@
     task_backendopt = taskdef(task_backendopt, 
                                         ['rtype'], "Back-end optimisations") 
 
+    def task_stackcheckinsertion(self):
+        from pypy.translator.transform import insert_ll_stackcheck
+        insert_ll_stackcheck(self.translator)
+        
+    task_stackcheckinsertion = taskdef(
+        task_stackcheckinsertion, 
+        ['?backendopt', 'rtype', 'annotate'], 
+        "inserting stack checks")
+
     def task_database_c(self):
         translator = self.translator
         opt = self.options
@@ -237,7 +246,7 @@
         self.database = database
     #
     task_database_c = taskdef(task_database_c, 
-                            ['?backendopt', '?rtype', '?annotate'], 
+                            ['stackcheckinsertion', '?backendopt', '?rtype', '?annotate'], 
                             "Creating database for generating c source")
     
     def task_source_c(self):  # xxx messy
@@ -301,7 +310,7 @@
         log.llinterpret.event("result -> %s" % v)
     #
     task_llinterpret = taskdef(task_llinterpret, 
-                               ['?backendopt', 'rtype'], 
+                               ['stackcheckinsertion', '?backendopt', 'rtype'], 
                                "LLInterpreting")
 
     def task_source_llvm(self):
@@ -320,7 +329,7 @@
         self.log.info("written: %s" % (llvm_filename,))
     #
     task_source_llvm = taskdef(task_source_llvm, 
-                               ['backendopt', 'rtype'], 
+                               ['stackcheckinsertion', 'backendopt', 'rtype'], 
                                "Generating llvm source")
 
     def task_compile_llvm(self):

Modified: pypy/dist/pypy/translator/interactive.py
==============================================================================
--- pypy/dist/pypy/translator/interactive.py	(original)
+++ pypy/dist/pypy/translator/interactive.py	Fri Apr  7 20:42:39 2006
@@ -50,6 +50,7 @@
         'rtype': ['insist'],
         'ootype': [],
         'backendopt': ['merge_if_blocks'],
+        'stackcheckinsertion': [],
         'database_c': ['gc', 'stackless'],
         'source_llvm': ['gc', 'stackless'],
         'source_c': [],

Modified: pypy/dist/pypy/translator/transform.py
==============================================================================
--- pypy/dist/pypy/translator/transform.py	(original)
+++ pypy/dist/pypy/translator/transform.py	Fri Apr  7 20:42:39 2006
@@ -13,6 +13,7 @@
 from pypy.objspace.flow.model import c_last_exception, checkgraph
 from pypy.annotation import model as annmodel
 from pypy.rpython.rstack import stack_check
+from pypy.rpython.lltypesystem import lltype
 
 def checkgraphs(self, blocks):
     seen = {}
@@ -178,6 +179,41 @@
         unwind_op = SpaceOperation('simple_call', [Constant(stack_check)], v)
         caller_block.operations.insert(0, unwind_op)
 
+def insert_ll_stackcheck(translator):
+    from pypy.translator.backendopt.support import calculate_call_graph
+    from pypy.rpython.module.ll_stack import ll_stack_check
+    from pypy.tool.algo.graphlib import Edge, make_edge_dict, break_cycles
+    rtyper = translator.rtyper
+    graph = rtyper.annotate_helper(ll_stack_check, [])
+    rtyper.specialize_more_blocks()
+    stack_check_ptr = rtyper.getcallable(graph)
+    stack_check_ptr_const = Constant(stack_check_ptr, lltype.typeOf(stack_check_ptr))
+    call_graph = calculate_call_graph(translator)
+    edges = []
+    graphs_to_patch = {}
+    insert_in = {}
+    for caller, all_callees in call_graph.iteritems():
+        for callee, block in all_callees.iteritems():
+            if getattr(getattr(callee, 'func', None),
+                       'insert_stack_check_here', False):
+                insert_in[callee.startblock] = True
+                continue
+            edge = Edge(caller, callee)
+            edge.block = block
+            edges.append(edge)
+
+    edgedict = make_edge_dict(edges)
+    for edge in break_cycles(edgedict, edgedict):
+        block = edge.block
+        insert_in[block] = True
+        
+    for block in insert_in:
+        v = Variable()
+        v.concretetype = lltype.Void
+        unwind_op = SpaceOperation('direct_call', [stack_check_ptr_const], v)
+        block.operations.insert(0, unwind_op)
+           
+
 default_extra_passes = [
     transform_allocate,
     ]



More information about the Pypy-commit mailing list