[pypy-svn] r65495 - in pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Fri May 29 17:06:00 CEST 2009


Author: cfbolz
Date: Fri May 29 17:05:58 2009
New Revision: 65495

Modified:
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py
Log:
support for functions that are annotated to be pure


Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py	Fri May 29 17:05:58 2009
@@ -270,7 +270,8 @@
             assert not portal, "portal has been hidden!"
             graph = make_calling_stub(codewriter.rtyper, graph)
         self.graph = graph
-        self.raise_analyzer = RaiseAnalyzer(self.cpu.rtyper.annotator.translator)
+        self.translator = self.cpu.rtyper.annotator.translator
+        self.raise_analyzer = RaiseAnalyzer(self.translator)
 
     def assemble(self):
         """Assemble the opcodes for self.bytecode."""
@@ -928,12 +929,18 @@
         calldescr, non_void_args = self.codewriter.getcalldescr(op.args[0],
                                                                 args,
                                                                 op.result)
+        pure = False
+        if op.opname == "direct_call":
+            func = get_funcobj(op.args[0].value)._callable
+            pure = getattr(func, "_pure_function_", False)
         try:
             canraise = self.raise_analyzer.can_raise(op)
         except lltype.DelayedPointer:
             canraise = True  # if we need to look into the delayed ptr that is
                              # the portal, then it's certainly going to raise
-        if canraise:
+        if pure:
+            self.emit('residual_call_pure')
+        elif canraise:
             self.emit('residual_call')
         else:
             self.emit('residual_call_noexception')

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py	Fri May 29 17:05:58 2009
@@ -1,5 +1,5 @@
 import py
-from pypy.rlib.jit import JitDriver, we_are_jitted
+from pypy.rlib.jit import JitDriver, we_are_jitted, hint
 from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats
 from pypy.jit.backend.llgraph import runner
 from pypy.jit.metainterp import support, codewriter, pyjitpl, history
@@ -265,6 +265,17 @@
         assert res == 42
         self.check_history_(int_add=1, int_mul=0, call=1, guard_no_exception=0)
 
+    def test_residual_call_pure(self):
+        def externfn(x, y):
+            return x * y
+        externfn._pure_function_ = True
+        def f(n):
+            n = hint(n, promote=True)
+            return externfn(n, n+1)
+        res = self.interp_operations(f, [6])
+        assert res == 42
+        self.check_history_(int_add=0, int_mul=0, call=0)
+
     def test_constant_across_mp(self):
         myjitdriver = JitDriver(greens = [], reds = ['n'])
         class X(object):



More information about the Pypy-commit mailing list