[pypy-svn] r21047 - in pypy/dist/pypy/jit: . test

arigo at codespeak.net arigo at codespeak.net
Sun Dec 11 16:18:29 CET 2005


Author: arigo
Date: Sun Dec 11 16:18:27 2005
New Revision: 21047

Modified:
   pypy/dist/pypy/jit/llabstractinterp.py
   pypy/dist/pypy/jit/test/test_llabstractinterp.py
Log:
Don't residualize called graphs if they are called without any
LLConcreteValue.  Write a call to the original graph instead.


Modified: pypy/dist/pypy/jit/llabstractinterp.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp.py	(original)
+++ pypy/dist/pypy/jit/llabstractinterp.py	Sun Dec 11 16:18:27 2005
@@ -590,44 +590,58 @@
     def op_same_as(self, op, a):
         return a
 
-    def op_direct_call(self, op, a_func, *args_a):
-        a_result = LLRuntimeValue(op.result)
+    def op_direct_call(self, op, *args_a):
+        a_result = self.handle_call(op, *args_a)
+        if a_result is None:
+            a_result = self.residualize(op, args_a)
+        return a_result
+
+    def handle_call(self, op, a_func, *args_a):
         v_func = a_func.maybe_get_constant()
-        if v_func is not None:
-            fnobj = v_func.value._obj
-            if (hasattr(fnobj, 'graph') and
-                not getattr(fnobj._callable, 'suggested_primitive', False)):
-                origgraph = fnobj.graph
-
-                # for now, we need to force all arguments
-                for a in args_a:
-                    a.forcevarorconst(self)
-                
-                graphstate, args_a = self.interp.schedule_graph(
-                    args_a, origgraph)
-                #print 'SCHEDULE_GRAPH', args_a, '==>', graphstate.copygraph.name
-                if graphstate.state != "during":
-                    print 'ENTERING', graphstate.copygraph.name, args_a
-                    graphstate.complete()
-                    if (graphstate.a_return is not None and
-                        graphstate.a_return.maybe_get_constant() is not None):
-                        a_result = graphstate.a_return
-                    print 'LEAVING', graphstate.copygraph.name, graphstate.a_return
-                
-                origfptr = v_func.value
-                ARGS = []
-                new_args_a = []
-                for a in args_a:
-                    if not isinstance(a, LLConcreteValue):
-                        ARGS.append(a.getconcretetype())
-                        new_args_a.append(a)
-                args_a = new_args_a
-                TYPE = lltype.FuncType(
-                   ARGS, lltype.typeOf(origfptr).TO.RESULT)
-                fptr = lltype.functionptr(
-                   TYPE, graphstate.copygraph.name, graph=graphstate.copygraph)
-                a_func = LLRuntimeValue(const(fptr))
-        self.residual("direct_call", [a_func] + list(args_a), a_result) 
+        if v_func is None:
+            return None
+        fnobj = v_func.value._obj
+        if not hasattr(fnobj, 'graph'):
+            return None
+        if getattr(fnobj._callable, 'suggested_primitive', False):
+            return None
+
+        origgraph = fnobj.graph
+
+        # for now, we need to force all arguments
+        any_concrete = False
+        for a in args_a:
+            a.forcevarorconst(self)
+            any_concrete = any_concrete or isinstance(a,LLConcreteValue)
+        if not any_concrete:
+            return None
+
+        a_result = LLRuntimeValue(op.result)
+        graphstate, args_a = self.interp.schedule_graph(
+            args_a, origgraph)
+        #print 'SCHEDULE_GRAPH', args_a, '==>', graphstate.copygraph.name
+        if graphstate.state != "during":
+            print 'ENTERING', graphstate.copygraph.name, args_a
+            graphstate.complete()
+            if (graphstate.a_return is not None and
+                graphstate.a_return.maybe_get_constant() is not None):
+                a_result = graphstate.a_return
+            print 'LEAVING', graphstate.copygraph.name, graphstate.a_return
+
+        origfptr = v_func.value
+        ARGS = []
+        new_args_a = []
+        for a in args_a:
+            if not isinstance(a, LLConcreteValue):
+                ARGS.append(a.getconcretetype())
+                new_args_a.append(a)
+        args_a = new_args_a
+        TYPE = lltype.FuncType(
+           ARGS, lltype.typeOf(origfptr).TO.RESULT)
+        fptr = lltype.functionptr(
+           TYPE, graphstate.copygraph.name, graph=graphstate.copygraph)
+        a_func = LLRuntimeValue(const(fptr))
+        self.residual("direct_call", [a_func] + args_a, a_result) 
         return a_result
 
     def op_getfield(self, op, a_ptr, a_attrname):

Modified: pypy/dist/pypy/jit/test/test_llabstractinterp.py
==============================================================================
--- pypy/dist/pypy/jit/test/test_llabstractinterp.py	(original)
+++ pypy/dist/pypy/jit/test/test_llabstractinterp.py	Sun Dec 11 16:18:27 2005
@@ -255,7 +255,7 @@
     # XXX fragile test: at the moment, the two branches of the 'if' are not
     # being merged at all because 's' was forced in one case only.
     assert insns == {'direct_call': 1, 'int_is_true': 1, 'int_add': 2,
-                     'malloc': 1, 'setfield': 2, 'getfield': 1}
+                     'malloc': 1, 'setfield': 1, 'getfield': 1}
 
 def test_unique_virtualptrs():
     S = lltype.GcStruct('S', ('n', lltype.Signed))
@@ -284,3 +284,14 @@
         return s.n1
     graph2, insns = abstrinterp(ll_function, [], [])
     assert insns == {}
+
+def test_residual_direct_call():
+    def ll_uninteresting(x, y):
+        return x * y
+    def ll_function(a, b):
+        return ll_uninteresting(a+b, b+1)
+    graph2, insns = abstrinterp(ll_function, [2, 5], [0])
+    # ll_uninteresting() should not be residualized because it is only passed
+    # non-concrete values, so 'insns' should only see the residualized
+    # ll_function().
+    assert insns == {'direct_call': 1, 'int_add': 2}



More information about the Pypy-commit mailing list