[pypy-svn] r17475 - in pypy/dist/pypy: annotation rpython/test translator translator/test

pedronis at codespeak.net pedronis at codespeak.net
Sun Sep 11 22:35:22 CEST 2005


Author: pedronis
Date: Sun Sep 11 22:35:19 2005
New Revision: 17475

Modified:
   pypy/dist/pypy/annotation/bookkeeper.py
   pypy/dist/pypy/rpython/test/test_rpbc.py
   pypy/dist/pypy/translator/annrpython.py
   pypy/dist/pypy/translator/test/test_annrpython.py
Log:
emulate_pbc_call should not require position_key to be set

support specifying a calalback that will be called with annotator, graph each time one of the involved callable
result gets generalized



Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py	(original)
+++ pypy/dist/pypy/annotation/bookkeeper.py	Sun Sep 11 22:35:19 2005
@@ -522,8 +522,8 @@
 
             callfamily.patterns.update({shape: True})
  
-    def pbc_call(self, pbc, args, implicit_init):
-        if not implicit_init:
+    def pbc_call(self, pbc, args, implicit_init=False, emulated=None):
+        if not implicit_init and not emulated:
             fn, block, i = self.position_key
             assert block.operations[i].opname in ('call_args', 'simple_call')
             assert self.annotator.binding(block.operations[i].args[0], extquery=True) is pbc
@@ -541,17 +541,25 @@
                             if func is not None]
         mono = len(nonnullcallables) == 1
 
+        if emulated is not None:
+            if emulated is True:
+                context = None
+            else:
+                context = emulated
+        else:
+            context = 'current'
+
         for func, classdef in nonnullcallables:
             if isclassdef(classdef): 
                 s_self = SomeInstance(classdef)
                 args1 = args.prepend(s_self)
             else:
                 args1 = args
-            results.append(self.pycall(func, args1, mono))
+            results.append(self.pycall(func, args1, mono, context=context))
 
         return unionof(*results) 
 
-    def emulate_pbc_call(self, unique_key, pbc, args_s, replace=[]):
+    def emulate_pbc_call(self, unique_key, pbc, args_s, replace=[], callback=None):
         args = self.build_args("simple_call", args_s)
         shape = args.rawshape()
         emulated_pbc_calls = self.emulated_pbc_calls
@@ -564,7 +572,12 @@
                 del emulated_pbc_calls[other_key]
         emulated_pbc_calls[unique_key] = pbc, shape
 
-        return self.pbc_call(pbc, args, True)
+        if callback is None:
+            emulated = True
+        else:
+            emulated = callback
+
+        return self.pbc_call(pbc, args, emulated=emulated)
 
     # decide_callable(position, func, args, mono) -> callb, key
     # query_spaceop_callable(spaceop) -> pbc, isspecialcase
@@ -644,13 +657,17 @@
         return inputcells
  
 
-    def pycall(self, func, args, mono):
+    def pycall(self, func, args, mono, context='current'):
         if func is None:   # consider None as a NULL function pointer
             return SomeImpossibleValue()
 
         # decide and pick if necessary a specialized version
         base_func = func
-        func, key = decide_callable(self, self.position_key, func, args, mono, unpacked=True)
+        if context == 'current':
+            position_key = self.position_key
+        else:
+            position_key = None
+        func, key = decide_callable(self, position_key, func, args, mono, unpacked=True)
         
         if func is None:
             assert isinstance(key, SomeObject)
@@ -675,11 +692,15 @@
         assert isinstance(func, FunctionType), "[%s] expected user-defined function, got %r" % (self.whereami(), func)
 
         inputcells = self.get_inputcells(func, args)
-
-        r = self.annotator.recursivecall(func, self.position_key, inputcells)
+        if context == 'current':
+            whence = self.position_key
+        else:
+            whence = context
+        r = self.annotator.recursivecall(func, whence, inputcells)
 
         # if we got different specializations keys for a same site, mix previous results for stability
         if key is not None:
+            assert context == 'current'
             occurence = (base_func, self.position_key)
             try:
                 prev_key, prev_r = self.spec_callsite_keys_results[occurence]

Modified: pypy/dist/pypy/rpython/test/test_rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rpbc.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rpbc.py	Sun Sep 11 22:35:19 2005
@@ -850,15 +850,14 @@
 def test_hlinvoke_simple():
     def f(a,b):
         return a + b
+    from pypy.translator import translator
     from pypy.translator import annrpython
-    a = annrpython.RPythonAnnotator()
+    a = annrpython.RPythonAnnotator(translator.Translator(simplifying=True))
     from pypy.annotation import model as annmodel
     
-    def g():
-        f(2,3)
-        f(4,5)
-
-    a.build_types(g, [])
+    s_f = a.bookkeeper.immutablevalue(f) 
+    a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()])
+    a.complete()
 
     from pypy.rpython import rtyper
     rt = rtyper.RPythonTyper(a)
@@ -870,7 +869,6 @@
 
     from pypy.rpython import annlowlevel
 
-    s_f = a.bookkeeper.immutablevalue(f)
     r_f = rt.getrepr(s_f)
 
     s_R = a.bookkeeper.immutablevalue(r_f)

Modified: pypy/dist/pypy/translator/annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/annrpython.py	(original)
+++ pypy/dist/pypy/translator/annrpython.py	Sun Sep 11 22:35:19 2005
@@ -269,14 +269,23 @@
 
     #___ interface for annotator.bookkeeper _______
 
-    def recursivecall(self, func, position_key, inputcells):
-        parent_fn, parent_block, parent_index = position_key
+    def recursivecall(self, func, whence, inputcells): # whence = position_key|callback taking the annotator, graph 
+        if isinstance(whence, tuple):
+            parent_fn, parent_block, parent_index = position_key = whence
+        else:
+            parent_fn = position_key = None
         graph = self.getflowgraph(func, parent_fn, position_key)
         # self.notify[graph.returnblock] is a dictionary of call
         # points to this func which triggers a reflow whenever the
         # return block of this graph has been analysed.
         callpositions = self.notify.setdefault(graph.returnblock, {})
-        callpositions[position_key] = True
+        if whence is not None:
+            if callable(whence):
+                def callback():
+                    whence(self, graph)
+            else:
+                callback = whence
+            callpositions[callback] = True
 
         # generalize the function's input arguments
         self.addpendingblock(func, graph.startblock, inputcells, position_key)
@@ -584,8 +593,11 @@
             self.addpendingblock(fn, link.target, cells)
         if block in self.notify:
             # reflow from certain positions when this block is done
-            for position_key in self.notify[block]:
-                self.reflowfromposition(position_key)
+            for callback in self.notify[block]:
+                if isinstance(callback, tuple):
+                    self.reflowfromposition(callback) # callback is a position
+                else:
+                    callback()
 
 
     #___ creating the annotations based on operations ______

Modified: pypy/dist/pypy/translator/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/test/test_annrpython.py	(original)
+++ pypy/dist/pypy/translator/test/test_annrpython.py	Sun Sep 11 22:35:19 2005
@@ -1664,6 +1664,44 @@
         s = a.build_types(g, [int])
         assert None not in s.prebuiltinstances
 
+    def test_emulated_pbc_call_simple(self):
+        def f(a,b):
+            return a + b
+        from pypy.translator import translator
+        from pypy.translator import annrpython
+        a = annrpython.RPythonAnnotator(translator.Translator(simplifying=True))
+        from pypy.annotation import model as annmodel
+
+        s_f = a.bookkeeper.immutablevalue(f) 
+        a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()])
+        a.complete()
+
+        assert f in a.translator.flowgraphs
+        assert a.binding(a.translator.flowgraphs[f].getreturnvar()).knowntype == int
+
+    def test_emulated_pbc_call_callback(self):
+        def f(a,b):
+            return a + b
+        from pypy.translator import translator
+        from pypy.translator import annrpython
+        a = annrpython.RPythonAnnotator(translator.Translator(simplifying=True))
+        from pypy.annotation import model as annmodel
+
+        memo = []
+        def callb(ann, graph):
+            memo.append(annmodel.SomeInteger().contains(ann.binding(graph.getreturnvar())))
+
+        s_f = a.bookkeeper.immutablevalue(f) 
+        s = a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()],
+                                          callback=callb)
+        assert s == annmodel.SomeImpossibleValue()
+        a.complete()
+
+        assert f in a.translator.flowgraphs
+        assert a.binding(a.translator.flowgraphs[f].getreturnvar()).knowntype == int
+        assert len(memo) >= 1
+        for t in memo:
+            assert t
 
 def g(n):
     return [0,1,2,n]



More information about the Pypy-commit mailing list