[pypy-svn] r32119 - in pypy/dist/pypy/jit: hintannotator hintannotator/test tl

arigo at codespeak.net arigo at codespeak.net
Sun Sep 10 14:07:28 CEST 2006


Author: arigo
Date: Sun Sep 10 14:07:26 2006
New Revision: 32119

Modified:
   pypy/dist/pypy/jit/hintannotator/bookkeeper.py
   pypy/dist/pypy/jit/hintannotator/model.py
   pypy/dist/pypy/jit/hintannotator/test/test_annotator.py
   pypy/dist/pypy/jit/tl/tlr.py
Log:
(pedronis, arigo)

Add a form of propagation of green variables, for the cases that don't
make merge points fail to unify in the timeshifted graphs because of it.

XXX needs tons of comments in the source code to explain *how* it does
this.



Modified: pypy/dist/pypy/jit/hintannotator/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/jit/hintannotator/bookkeeper.py	(original)
+++ pypy/dist/pypy/jit/hintannotator/bookkeeper.py	Sun Sep 10 14:07:26 2006
@@ -85,7 +85,12 @@
             origin = self.originflags[self.position_key]
         except KeyError:
             from pypy.jit.hintannotator import model as hintmodel
-            origin = hintmodel.OriginFlags()
+            if len(self.position_key) == 3:
+                graph, block, i = self.position_key
+                spaceop = block.operations[i]
+            else:
+                spaceop = None
+            origin = hintmodel.OriginFlags(self, spaceop)
             self.originflags[self.position_key] = origin
         return origin
 

Modified: pypy/dist/pypy/jit/hintannotator/model.py
==============================================================================
--- pypy/dist/pypy/jit/hintannotator/model.py	(original)
+++ pypy/dist/pypy/jit/hintannotator/model.py	Sun Sep 10 14:07:26 2006
@@ -32,6 +32,10 @@
     fixed = False
     read_positions = None
 
+    def __init__(self, bookkeeper=None, spaceop=None):
+        self.bookkeeper = bookkeeper
+        self.spaceop = spaceop
+
     def __repr__(self):
         if self.fixed:
             s = "fixed "
@@ -53,6 +57,58 @@
                 for p in self.read_positions:
                     annotator.reflowfromposition(p)
 
+    def greenargs(self, frame=None):
+        annotator = self.bookkeeper.annotator
+        if frame is None:
+            frame = GreenHandlerFrame(annotator)
+        if self.spaceop.opname == 'direct_call':     # ah haa
+            return frame.greencallresult(self.spaceop)
+        else:
+            for v in self.spaceop.args:
+                if not frame.greenvar(v):
+                    return False
+            return True
+
+
+class GreenHandlerFrame(object):
+
+    def __init__(self, annotator, parentframe=None):
+        self.annotator = annotator
+        self.parentframe = parentframe
+        self.inputarg2actualarg = {}    # {origin: annotation}
+
+    def greenvar(self, v):
+        hs = self.annotator.binding(v)
+        if isinstance(hs, SomeLLAbstractConstant) and len(hs.origins) == 1:
+            [o] = hs.origins.keys()
+            if o in self.inputarg2actualarg:
+                hs_actual = self.inputarg2actualarg[o]
+                return hs_actual.is_green(self.parentframe)
+        return hs.is_green(self)
+
+    def greencallresult(self, spaceop):
+##        print spaceop
+##        if str(spaceop.result) == 'v58':
+##            import pdb; pdb.set_trace()
+        args_hs = [self.annotator.binding(v) for v in spaceop.args]
+        hs_result = self.annotator.binding(spaceop.result)
+        hs_f1 = args_hs.pop(0)
+        fnobj = hs_f1.const._obj
+        input_args_hs = list(args_hs)
+        bk = self.annotator.bookkeeper
+        graph = bk.get_graph_for_call(fnobj.graph,
+                                      hs_result.is_fixed(),
+                                      input_args_hs)
+        newframe = GreenHandlerFrame(self.annotator, parentframe=self)
+        for hs_inp_arg, hs_arg in zip(input_args_hs, args_hs):
+            if isinstance(hs_arg, SomeLLAbstractConstant):
+                assert len(hs_inp_arg.origins) == 1
+                [o] = hs_inp_arg.origins.keys()
+                newframe.inputarg2actualarg[o] = hs_arg
+        return newframe.greenvar(graph.getreturnvar())
+
+# ____________________________________________________________
+
 
 class SomeLLAbstractValue(annmodel.SomeObject):
 
@@ -60,13 +116,18 @@
         self.concretetype = T
         assert self.__class__ != SomeLLAbstractValue
 
+    def is_green(self, frame=None):
+        return False
+
 
 class SomeLLAbstractConstant(SomeLLAbstractValue):
 
-    def __init__(self, T, origins, eager_concrete=False):
+    def __init__(self, T, origins, eager_concrete=False, myorigin=None):
         SomeLLAbstractValue.__init__(self, T)
         self.origins = origins
         self.eager_concrete = eager_concrete
+        self.myorigin = myorigin
+        assert myorigin is None or myorigin.spaceop is not None
 
     def fmt_origins(self, origins):
         counts = {}
@@ -84,19 +145,31 @@
             lst.append(s)
         return '<%s>' % (', '.join(lst),)
 
+    def fmt_myorigin(self, myorigin):
+        if myorigin is None:
+            return None
+        else:
+            return str(myorigin.spaceop.result)
+
     def is_fixed(self):
         for o in self.origins:
             if not o.fixed:
                 return False
         return True
 
+    def is_green(self, frame=None):
+        return (self.is_fixed() or self.eager_concrete or
+                self.concretetype is lltype.Void or
+                (self.myorigin is not None and
+                 self.myorigin.greenargs(frame)))
+
     def annotationcolor(self):
         """Compute the color of the variables with this annotation
         for the pygame viewer
         """
         if self.eager_concrete:
             return (0,100,0)     # green
-        elif self.is_fixed():
+        elif self.is_green():
             return (50,140,0)    # green-dark-cyan
         else:
             return None
@@ -260,6 +333,7 @@
             if fixed:
                 deps_hs.append(hs_res)
             hs_res = reorigin(hs_res, *deps_hs)
+            hs_res.myorigin = bookkeeper.myorigin()
 
         # we need to make sure that hs_res does not become temporarily less
         # general as a result of calling another specialized version of the
@@ -270,16 +344,20 @@
         S = hs_c1.concretetype.TO
         FIELD_TYPE = getattr(S, hs_fieldname.const)
         if S._hints.get('immutable', False):
-            d = setadd(hs_c1.origins, getbookkeeper().myorigin())
-            return SomeLLAbstractConstant(FIELD_TYPE, d)
+            origin = getbookkeeper().myorigin()
+            d = setadd(hs_c1.origins, origin)
+            return SomeLLAbstractConstant(FIELD_TYPE, d,
+                                          eager_concrete=hs_c1.eager_concrete,
+                                          myorigin=origin)
         else:
             return SomeLLAbstractVariable(FIELD_TYPE)
 
     def getsubstruct(hs_c1, hs_fieldname):
         S = hs_c1.concretetype.TO
         SUB_TYPE = getattr(S, hs_fieldname.const)
-        d = setadd(hs_c1.origins, getbookkeeper().myorigin())
-        return SomeLLAbstractConstant(lltype.Ptr(SUB_TYPE), d)
+        origin = getbookkeeper().myorigin()
+        d = setadd(hs_c1.origins, origin)
+        return SomeLLAbstractConstant(lltype.Ptr(SUB_TYPE), d, myorigin=origin)
 
 
 class __extend__(SomeLLAbstractContainer):
@@ -338,15 +416,24 @@
     def union((hs_c1, hs_c2)):
         assert hs_c1.concretetype == hs_c2.concretetype
         d = newset(hs_c1.origins, hs_c2.origins)
-        return SomeLLAbstractConstant(hs_c1.concretetype, d, eager_concrete=hs_c1.eager_concrete and hs_c2.eager_concrete)
+        if hs_c1.myorigin is hs_c2.myorigin:
+            myorigin = hs_c1.myorigin
+        else:
+            myorigin = None
+        return SomeLLAbstractConstant(hs_c1.concretetype, d,
+                                      eager_concrete = hs_c1.eager_concrete and
+                                                       hs_c2.eager_concrete,
+                                      myorigin = myorigin)
 
     def getarrayitem((hs_c1, hs_index)):
         A = hs_c1.concretetype.TO
         READ_TYPE = A.OF
         if A._hints.get('immutable', False):
-            d = newset(hs_c1.origins, hs_index.origins,
-                       {getbookkeeper().myorigin(): True})
-            return SomeLLAbstractConstant(READ_TYPE, d, eager_concrete=hs_c1.eager_concrete)
+            origin = getbookkeeper().myorigin()
+            d = newset(hs_c1.origins, hs_index.origins, {origin: True})
+            return SomeLLAbstractConstant(READ_TYPE, d,
+                                          eager_concrete=hs_c1.eager_concrete,
+                                          myorigin=origin)
         else:
             return SomeLLAbstractVariable(READ_TYPE)
 
@@ -452,18 +539,22 @@
 
 def const_unary(hs_c1):
     bk = getbookkeeper()
-    d = setadd(hs_c1.origins, bk.myorigin())
+    origin = bk.myorigin()
+    d = setadd(hs_c1.origins, origin)
     RESTYPE = bk.current_op_concretetype()
     return SomeLLAbstractConstant(RESTYPE, d,
-                                  eager_concrete = hs_c1.eager_concrete)
+                                  eager_concrete = hs_c1.eager_concrete,
+                                  myorigin = origin)
 
 def const_binary((hs_c1, hs_c2)):
     bk = getbookkeeper()
-    d = newset(hs_c1.origins, hs_c2.origins, {bk.myorigin(): True})
+    origin = bk.myorigin()
+    d = newset(hs_c1.origins, hs_c2.origins, {origin: True})
     RESTYPE = bk.current_op_concretetype()
     return SomeLLAbstractConstant(RESTYPE, d,
                                   eager_concrete = hs_c1.eager_concrete or
-                                                   hs_c2.eager_concrete)
+                                                   hs_c2.eager_concrete,
+                                  myorigin = origin)
 
 def setup(oplist, ValueCls, var_fn, ConstantCls, const_fn):
     for name in oplist:

Modified: pypy/dist/pypy/jit/hintannotator/test/test_annotator.py
==============================================================================
--- pypy/dist/pypy/jit/hintannotator/test/test_annotator.py	(original)
+++ pypy/dist/pypy/jit/hintannotator/test/test_annotator.py	Sun Sep 10 14:07:26 2006
@@ -6,6 +6,7 @@
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.objectmodel import hint
 from pypy.annotation import model as annmodel
+from pypy.objspace.flow import model as flowmodel
 from pypy.annotation.policy import AnnotatorPolicy
 from pypy.translator.backendopt.inline import auto_inlining
 from pypy import conftest
@@ -145,7 +146,10 @@
 def test_op_meet():
     def meet(hs1, hs2):
         bk = HintBookkeeper(None)
-        bk.enter(None)
+        block = flowmodel.Block([])
+        block.operations.append(flowmodel.SpaceOperation('x', [],
+                                                         flowmodel.Variable()))
+        bk.enter(("graph", block, 0))
         bk.current_op_concretetype = lambda: lltype.Signed     # hack
         return pair(hs1, hs2).int_add()
     av1, av2 = SomeLLAbstractVariable(lltype.Signed), SomeLLAbstractVariable(lltype.Signed)
@@ -439,6 +443,10 @@
     from pypy.jit.tl import tl
     hannotate(tl.interp, [str, int, int], policy=P_OOPSPEC_NOVIRTUAL)
 
+def test_hannotate_tlr_novirtual():
+    from pypy.jit.tl import tlr
+    hannotate(tlr.interpret, [str, int], policy=P_OOPSPEC_NOVIRTUAL)
+
 def test_hannotate_plus_minus():
     def ll_plus_minus(s, x, y):
         acc = x
@@ -519,3 +527,15 @@
     hs = hannotate(g, [bool], policy=P_OOPSPEC_NOVIRTUAL)    
     assert isinstance(hs, SomeLLAbstractConstant)
     assert hs.concretetype == lltype.Signed    
+
+
+def test_more_green():
+    def f(x):
+        z = x + 1
+        x2 = hint(x, concrete=True)
+        return z
+
+    hs = hannotate(f, [int])
+    assert isinstance(hs, SomeLLAbstractConstant)
+    assert hs.is_green()
+    assert not hs.is_fixed()

Modified: pypy/dist/pypy/jit/tl/tlr.py
==============================================================================
--- pypy/dist/pypy/jit/tl/tlr.py	(original)
+++ pypy/dist/pypy/jit/tl/tlr.py	Sun Sep 10 14:07:26 2006
@@ -19,11 +19,11 @@
         opcode = hint(ord(bytecode[pc]), concrete=True)
         pc += 1
         if opcode == MOV_A_R:
-            n = ord(bytecode[pc]); hint(n, concrete=True)
+            n = ord(bytecode[pc])
             pc += 1
             regs[n] = a
         elif opcode == MOV_R_A:
-            n = ord(bytecode[pc]); hint(n, concrete=True)
+            n = ord(bytecode[pc])
             pc += 1
             a = regs[n]
         elif opcode == JUMP_IF_A:
@@ -32,16 +32,16 @@
             if a:
                 pc = target
         elif opcode == SET_A:
-            a = ord(bytecode[pc]); hint(a, concrete=True)
+            a = ord(bytecode[pc])
             pc += 1
         elif opcode == ADD_R_TO_A:
-            n = ord(bytecode[pc]); hint(n, concrete=True)
+            n = ord(bytecode[pc])
             pc += 1
             a += regs[n]
         elif opcode == RETURN_A:
             return a
         elif opcode == ALLOCATE:
-            n = ord(bytecode[pc]); hint(n, concrete=True)
+            n = ord(bytecode[pc])
             pc += 1
             regs = [0] * n
         elif opcode == NEG_A:



More information about the Pypy-commit mailing list