Author: Carl Friedrich Bolz <cfb...@gmx.de>
Branch: better-storesink
Changeset: r87727:c87a2cec8f9d
Date: 2016-09-21 14:54 +0200
http://bitbucket.org/pypy/pypy/changeset/c87a2cec8f9d/

Log:    cache elidable calls

diff --git a/rpython/translator/backendopt/cse.py 
b/rpython/translator/backendopt/cse.py
--- a/rpython/translator/backendopt/cse.py
+++ b/rpython/translator/backendopt/cse.py
@@ -278,9 +278,26 @@
                        (representative_arg(op.result), ))
                 self.purecache[key] = op.args[2]
 
-            if has_side_effects(op):
+            can_fold_op = can_fold(op)
+            has_side_effects_op = has_side_effects(op)
+            if op.opname == "direct_call":
+                funcobj = op.args[0].value._obj
+                func = getattr(funcobj, '_callable', None)
+                elidable = getattr(func, "_elidable_function_", False)
+                if elidable:
+                    # can't hash pointers, so use the graph directly
+                    key = ("direct_call", op.result.concretetype,
+                           (funcobj.graph, ) +
+                               tuple([representative_arg(arg)
+                                   for arg in op.args[1:]]))
+                    can_fold_op = True
+            elif can_fold_op:
+                key = (op.opname, op.result.concretetype,
+                       tuple([representative_arg(arg) for arg in op.args]))
+
+
+            if has_side_effects_op:
                 self._clear_heapcache_for_effects_of_op(op)
-                continue
 
             # foldable operations
             if op.opname == "cast_pointer":
@@ -290,10 +307,8 @@
                 self.new_unions.union(op.args[0], op.result)
                 # don't do anything further
                 continue
-            if not can_fold(op):
+            if not can_fold_op:
                 continue
-            key = (op.opname, op.result.concretetype,
-                   tuple([representative_arg(arg) for arg in op.args]))
             res = self.purecache.get(key, None)
             if res is not None:
                 self._replace_with_result(op, res)
diff --git a/rpython/translator/backendopt/test/test_cse.py 
b/rpython/translator/backendopt/test/test_cse.py
--- a/rpython/translator/backendopt/test/test_cse.py
+++ b/rpython/translator/backendopt/test/test_cse.py
@@ -5,6 +5,7 @@
 from rpython.translator.backendopt import removenoops
 from rpython.flowspace.model import checkgraph, summary
 from rpython.conftest import option
+from rpython.rlib import jit
 
 class TestStoreSink(object):
     def translate(self, func, argtypes):
@@ -556,6 +557,16 @@
             return len(l)
         self.check(f, [int], fullopts=True, getarraysize=0)
 
+    def test_remove_duplicate_elidable_call(self):
+        @jit.elidable
+        def p(x):
+            return x + 1
+
+        def f(x):
+            return p(x) + p(x)
+
+        self.check(f, [int], fullopts=False, direct_call=1)
+
 
 def fakevar(name='v'):
     var = Variable(name)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to