[pypy-svn] r32573 - in pypy/dist/pypy: jit/hintannotator/test jit/timeshifter jit/timeshifter/test rpython/lltypesystem translator

arigo at codespeak.net arigo at codespeak.net
Fri Sep 22 13:00:19 CEST 2006


Author: arigo
Date: Fri Sep 22 13:00:15 2006
New Revision: 32573

Modified:
   pypy/dist/pypy/jit/hintannotator/test/test_annotator.py
   pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
   pypy/dist/pypy/jit/timeshifter/transform.py
   pypy/dist/pypy/rpython/lltypesystem/rclass.py
   pypy/dist/pypy/translator/simplify.py
Log:
(arre, arigo)

* added the immutable hint to the 'typeptr' part of all instance
  objects.

* jit green calls: check for side-effects.

* made test_simple_method pass, for now by assuming that in all
  indirect calls the red box containing the function pointer is
  actually a compile-time constant.



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	Fri Sep 22 13:00:15 2006
@@ -556,14 +556,14 @@
 
 def test_simple_meth():
     class Base(object):
-
         def m(self):
             raise NotImplementedError
+        pass  # for inspect.getsource() bugs
 
     class Concrete(Base):
-
         def m(self):
             return 42
+        pass  # for inspect.getsource() bugs
 
     def f(flag):
         if flag:

Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py	Fri Sep 22 13:00:15 2006
@@ -912,6 +912,18 @@
         assert res == 23
         self.check_insns({'int_gt': 1})
 
+    def test_green_with_side_effects(self):
+        S = lltype.GcStruct('S', ('flag', lltype.Bool))
+        s = lltype.malloc(S)
+        def ll_set_flag(s):
+            s.flag = True
+        def ll_function():
+            s.flag = False
+            ll_set_flag(s)
+            return s.flag
+        res = self.timeshift(ll_function, [], [])
+        assert res is True
+        self.check_insns({'setfield': 2, 'getfield': 1})
 
     def test_recursive_call(self):
         def ll_pseudo_factorial(n, fudge):
@@ -1006,3 +1018,25 @@
         res = self.timeshift(f, [True, -1000], [0])
         assert res == f(True, -1000)
         self.check_insns({'int_ge': 2, 'int_add': 1})
+
+    def test_simple_meth(self):
+        class Base(object):
+            def m(self):
+                raise NotImplementedError
+            pass  # for inspect.getsource() bugs
+
+        class Concrete(Base):
+            def m(self):
+                return 42
+            pass  # for inspect.getsource() bugs
+
+        def f(flag):
+            if flag:
+                o = Base()
+            else:
+                o = Concrete()
+            return o.m()
+
+        res = self.timeshift(f, [False], [0], policy=P_NOVIRTUAL)
+        assert res == 42
+        self.check_insns({})

Modified: pypy/dist/pypy/jit/timeshifter/transform.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/transform.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/transform.py	Fri Sep 22 13:00:15 2006
@@ -7,6 +7,7 @@
 from pypy.rpython.rmodel import inputconst
 from pypy.translator.unsimplify import varoftype, copyvar
 from pypy.translator.unsimplify import split_block, split_block_at_start
+from pypy.translator.simplify import rec_op_has_side_effects
 from pypy.translator.backendopt.ssa import SSA_to_SSI
 from pypy.translator.backendopt import support
 
@@ -338,8 +339,11 @@
         else:
             hs_res = self.hannotator.binding(spaceop.result)
             if hs_res.is_green():
-                # all-green arguments and result
-                return 'green'
+                # all-green arguments and result.
+                # Does the function have side-effects?
+                t = self.hannotator.base_translator
+                if not rec_op_has_side_effects(t, spaceop):
+                    return 'green'
         colors = {}
         for graph, tsgraph in self.graphs_from(spaceop):
             color = self.graph_calling_color(tsgraph)
@@ -367,8 +371,14 @@
             # but only has the hidden side-effect of putting it in the jitstate
         else:
             c_targets = inputconst(lltype.Void, targets)
-            self.genop(block, 'indirect_%s_call' % (color,),
-                       op.args[:-1] + [c_targets])
+            args_v = op.args[:-1] + [c_targets]
+            hs_func = self.hannotator.binding(args_v[0])
+            if not hs_func.is_green():
+                # XXX for now, assume that it will be a constant red box
+                v_greenfunc = self.genop(block, 'revealconst', [args_v[0]],
+                                  result_type = originalconcretetype(hs_func))
+                args_v[0] = v_greenfunc
+            self.genop(block, 'indirect_%s_call' % (color,), args_v)
 
     def handle_red_call(self, block, pos, color='red'):
         # the 'save_locals' pseudo-operation is used to save all
@@ -425,9 +435,25 @@
         op.opname = 'green_call'
 
     def handle_yellow_call(self, block, pos):
+        op = block.operations[pos]
+        hs_result = self.hannotator.binding(op.result)
+        if not hs_result.is_green():
+            # yellow calls are supposed to return greens,
+            # add an indirection if it's not the case
+            # XXX a bit strange
+            RESULT = originalconcretetype(hs_result)
+            v_tmp = varoftype(RESULT)
+            hs = hintmodel.SomeLLAbstractConstant(RESULT, {})
+            self.hannotator.setbinding(v_tmp, hs)
+            v_real_result = op.result
+            op.result = v_tmp
+            newop = SpaceOperation('same_as', [v_tmp], v_real_result)
+            block.operations.insert(pos+1, newop)
+
         link = support.split_block_with_keepalive(block, pos+1,
                                                   annotator=self.hannotator)
-        op = block.operations.pop(pos)
+        op1 = block.operations.pop(pos)
+        assert op1 is op
         assert len(block.operations) == pos
         nextblock = link.target
         varsalive = link.args

Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rclass.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rclass.py	Fri Sep 22 13:00:15 2006
@@ -57,7 +57,8 @@
 
 OBJECT_VTABLE = lltype.ForwardReference()
 CLASSTYPE = Ptr(OBJECT_VTABLE)
-OBJECT = GcStruct('object', ('typeptr', CLASSTYPE))
+OBJECT = GcStruct('object', ('typeptr', CLASSTYPE),
+                            hints = {'immutable': True})
 OBJECTPTR = Ptr(OBJECT)
 OBJECT_VTABLE.become(Struct('object_vtable',
                             ('parenttypeptr', CLASSTYPE),

Modified: pypy/dist/pypy/translator/simplify.py
==============================================================================
--- pypy/dist/pypy/translator/simplify.py	(original)
+++ pypy/dist/pypy/translator/simplify.py	Fri Sep 22 13:00:15 2006
@@ -406,23 +406,27 @@
         if block is graph.exceptblock:
             return False     # graphs explicitly raising have side-effects
         for op in block.operations:
-            if op.opname == "direct_call":
-                g = get_graph(op.args[0], translator)
-                if g is None:
-                    return False
-                if not has_no_side_effects(translator, g, newseen):
-                    return False
-            elif op.opname == "indirect_call":
-                graphs = op.args[-1].value
-                if graphs is None:
-                    return False
-                for g in graphs:
-                    if not has_no_side_effects(translator, g, newseen):
-                        return False
-            elif op_has_side_effects(op):
+            if rec_op_has_side_effects(translator, op, newseen):
                 return False
     return True
 
+def rec_op_has_side_effects(translator, op, seen=None):
+    if op.opname == "direct_call":
+        g = get_graph(op.args[0], translator)
+        if g is None:
+            return True
+        if not has_no_side_effects(translator, g, seen):
+            return True
+    elif op.opname == "indirect_call":
+        graphs = op.args[-1].value
+        if graphs is None:
+            return True
+        for g in graphs:
+            if not has_no_side_effects(translator, g, seen):
+                return True
+    else:
+        return op_has_side_effects(op)
+
 # ___________________________________________________________________________
 # remove operations if their result is not used and they have no side effects
 



More information about the Pypy-commit mailing list