[pypy-svn] r40444 - in pypy/branch/jit-virtual-world/pypy/jit/hintannotator: . test

arigo at codespeak.net arigo at codespeak.net
Tue Mar 13 16:20:51 CET 2007


Author: arigo
Date: Tue Mar 13 16:20:46 2007
New Revision: 40444

Modified:
   pypy/branch/jit-virtual-world/pypy/jit/hintannotator/annotator.py
   pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py
   pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py
Log:
(pedronis, arigo)

* deepfrozenlist[index] => return SomeLLAbstractConstant,
  which allows us to fix back through the getitem

* support for indirect calls to a family of graphs, some
  of which are recursively followed and some of which are not.


Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/annotator.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/hintannotator/annotator.py	(original)
+++ pypy/branch/jit-virtual-world/pypy/jit/hintannotator/annotator.py	Tue Mar 13 16:20:46 2007
@@ -29,6 +29,23 @@
         return True
 
 
+class StopAtXPolicy(HintAnnotatorPolicy):
+    """Useful for tests."""
+
+    def __init__(self, *funcs):
+        HintAnnotatorPolicy.__init__(self, novirtualcontainer=True,
+                                     oopspec=True)
+        self.funcs = funcs
+
+    def look_inside_graph(self, graph):
+        try:
+            if graph.func in self.funcs:
+                return False
+        except AttributeError:
+            pass
+        return True
+
+
 class HintAnnotator(RPythonAnnotator):
 
     def __init__(self, translator=None, base_translator=None, policy=None):

Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py	(original)
+++ pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py	Tue Mar 13 16:20:46 2007
@@ -105,6 +105,16 @@
                 deps.append(v)
 
 
+class PureCallOpOriginFlags(CallOpOriginFlags):
+
+    def record_dependencies(self, greenorigindependencies,
+                                  callreturndependencies):
+        OriginFlags.record_dependencies(self, greenorigindependencies,
+                                              callreturndependencies)
+        CallOpOriginFlags.record_dependencies(self, greenorigindependencies,
+                                                    callreturndependencies)
+
+
 class InputArgOriginFlags(OriginFlags):
 
     def __init__(self, bookkeeper, graph, i):
@@ -623,11 +633,6 @@
 # ____________________________________________________________
 
 def handle_highlevel_operation(bookkeeper, ll_func, *args_hs):
-    if bookkeeper.annotator.policy.novirtualcontainer:
-        # "blue variables" disabled, we just return a red var all the time.
-        RESULT = bookkeeper.current_op_concretetype()
-        return variableoftype(RESULT)
-
     # parse the oopspec and fill in the arguments
     operation_name, args = ll_func.oopspec.split('(', 1)
     assert args.endswith(')')
@@ -644,6 +649,20 @@
         args_hs.append(hs)
     # end of rather XXX'edly hackish parsing
 
+    if bookkeeper.annotator.policy.novirtualcontainer:
+        # "blue variables" disabled, we just return a red var all the time.
+        # Exception: an operation on a frozen container is constant-foldable.
+        RESULT = bookkeeper.current_op_concretetype()
+        if '.' in operation_name and args_hs[0].deepfrozen:
+            myorigin = bookkeeper.myorigin()
+            d = newset({myorigin: True}, *[hs_c.origins for hs_c in args_hs])
+            return SomeLLAbstractConstant(RESULT, d,
+                                          eager_concrete = False,   # probably
+                                          myorigin = myorigin)
+        else:
+            return variableoftype(RESULT)
+
+    # --- the code below is not used any more except by test_annotator.py ---
     if operation_name == 'newlist':
         from pypy.jit.hintannotator.vlist import oop_newlist
         handler = oop_newlist
@@ -669,21 +688,46 @@
     # the policy prevents us from following the call
     if not graph_list:       # no known target, give up
         return variableoftype(RESTYPE)
+    pure_call = True
     for graph in graph_list:
         if not bookkeeper.is_pure_graph(graph):
             # it's not calling pure graphs either, so the result
             # is entierely unknown
-            return variableoftype(RESTYPE)
+            pure_call = False
+            break
     # when calling pure graphs, consider the call as an operation.
     for hs in args_hs:
         if not isinstance(hs, SomeLLAbstractConstant):
-            return variableoftype(RESTYPE)
-    # if all arguments are SomeLLAbstractConstant, so can the result be.
-    origin = bookkeeper.myorigin()
-    d = newset({origin: True}, *[hs_c.origins for hs_c in args_hs])
-    return SomeLLAbstractConstant(RESTYPE, d,
-                                  eager_concrete = False,   # probably
-                                  myorigin = origin)
+            pure_call = False
+            break
+    if pure_call:
+        # if all arguments are SomeLLAbstractConstant, so can the result be.
+        myorigin = bookkeeper.myorigin()
+        d = newset({myorigin: True}, *[hs_c.origins for hs_c in args_hs])
+        h_res = SomeLLAbstractConstant(RESTYPE, d,
+                                       eager_concrete = False,   # probably
+                                       myorigin = myorigin)
+        fixed = myorigin.read_fixed()
+    else:
+        h_res = variableoftype(RESTYPE)
+        fixed = False
+
+    look_inside_graph = bookkeeper.annotator.policy.look_inside_graph
+    followable_graphs = [graph for graph in graph_list
+                               if look_inside_graph(graph)]
+    if followable_graphs:
+        # we can still follow this graph, even if we cannot follow all of them
+        tsgraphs_accum = []
+        bookkeeper.graph_family_call(followable_graphs, fixed, args_hs[1:],
+                                     tsgraphs_accum)
+        myorigin = bookkeeper.myorigin()
+        myorigin.any_called_graph = tsgraphs_accum[0]
+        if pure_call:
+            myorigin.__class__ = PureCallOpOriginFlags     # thud
+        else:
+            myorigin.__class__ = CallOpOriginFlags     # thud
+
+    return h_res
 
 # ____________________________________________________________
 #

Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py	(original)
+++ pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py	Tue Mar 13 16:20:46 2007
@@ -1,6 +1,7 @@
 import py
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.jit.hintannotator.annotator import HintAnnotator, HintAnnotatorPolicy
+from pypy.jit.hintannotator.annotator import StopAtXPolicy
 from pypy.jit.hintannotator.bookkeeper import HintBookkeeper
 from pypy.jit.hintannotator.model import *
 from pypy.rpython.lltypesystem import lltype
@@ -339,6 +340,16 @@
     hs = hannotate(ll_function, [int, int], policy=P_OOPSPEC)
     assert isinstance(hs, SomeLLAbstractContainer)
 
+def test_frozen_list():
+    lst = [5, 7, 9]
+    def ll_function(x):
+        mylist = hint(lst, deepfreeze=True)
+        z = mylist[x]
+        hint(z, concrete=True)
+        return z
+    hs = hannotate(ll_function, [int], policy=P_OOPSPEC_NOVIRTUAL)
+    assert hs.is_green()
+
 def test_simple_cast_pointer():
     GCS1 = lltype.GcStruct('s1', ('x', lltype.Signed))
     GCS2 = lltype.GcStruct('s2', ('sub', GCS1), ('y', lltype.Signed))
@@ -766,3 +777,80 @@
 
     hs = hannotate(ll_function, [int, int], policy=P_NOVIRTUAL)
     assert not hs.is_green()
+
+
+def test_indirect_sometimes_residual_pure_red_call():
+    def h1(x):
+        return x-2
+    def h2(x):
+        return x*4
+    l = [h1, h2]
+    def f(n, x):
+        frozenl = hint(l, deepfreeze=True)
+        h = frozenl[n&1]
+        return h(x)
+
+    P = StopAtXPolicy(h1)
+    P.oopspec = True
+    P.entrypoint_returns_red = False
+    hs, hannotator = hannotate(f, [int, int], policy=P, annotator=True)
+    assert not hs.is_green()
+    assert isinstance(hs, SomeLLAbstractConstant)
+
+    tsgraph = graphof(hannotator.translator, h2)
+    hs = hannotator.binding(tsgraph.getargs()[0])
+    assert not hs.is_green()
+
+
+def test_indirect_sometimes_residual_red_call():
+    class Stuff:
+        pass
+    stuff = Stuff()
+    def h1(x):
+        stuff.hello = 123
+        return x-2
+    def h2(x):
+        return x*4
+    l = [h1, h2]
+    def f(n, x):
+        frozenl = hint(l, deepfreeze=True)
+        h = frozenl[n&1]
+        return h(x)
+
+    P = StopAtXPolicy(h1)
+    P.entrypoint_returns_red = False
+    hs, hannotator = hannotate(f, [int, int], policy=P, annotator=True)
+    assert not hs.is_green()
+
+    tsgraph = graphof(hannotator.translator, h2)
+    hs = hannotator.binding(tsgraph.getargs()[0])
+    assert not hs.is_green()
+
+
+def test_indirect_sometimes_residual_pure_but_fixed_red_call():
+    def h1(x):
+        return x-2
+    def h2(x):
+        return x*4
+    l = [h1, h2]
+    def f(n, x):
+        frozenl = hint(l, deepfreeze=True)
+        h = frozenl[n&1]
+        z = h(x)
+        hint(z, concrete=True)
+        return z
+
+    P = StopAtXPolicy(h1)
+    P.entrypoint_returns_red = False
+    hs, hannotator = hannotate(f, [int, int], policy=P, annotator=True)
+    assert hs.is_green()
+
+    #tsgraph = graphof(hannotator.translator, h2)
+    #hs = hannotator.binding(tsgraph.getargs()[0])
+    #assert hs.is_green()
+
+    tsgraph = graphof(hannotator.translator, f)
+    hs = hannotator.binding(tsgraph.getargs()[0])
+    assert hs.is_green()
+    hs = hannotator.binding(tsgraph.getargs()[1])
+    assert hs.is_green()



More information about the Pypy-commit mailing list