[pypy-commit] pypy conditional_call_value: try to write elidable COND_CALL, will write tests

fijal noreply at buildbot.pypy.org
Wed May 6 17:14:34 CEST 2015


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: conditional_call_value
Changeset: r77161:e3fb7aa96597
Date: 2015-05-06 17:14 +0200
http://bitbucket.org/pypy/pypy/changeset/e3fb7aa96597/

Log:	try to write elidable COND_CALL, will write tests

diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -302,6 +302,7 @@
             opnum == rop.CALL_PURE or
             opnum == rop.COND_CALL or
             opnum == rop.COND_CALL_VALUE or
+            opnum == rop.COND_CALL_VALUE_PURE or
             opnum == rop.CALL_MAY_FORCE or
             opnum == rop.CALL_RELEASE_GIL or
             opnum == rop.CALL_ASSEMBLER):
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -428,6 +428,20 @@
             op = op.copy_and_change(rop.CALL, args=op.getarglist()[2:])
         self.emit_operation(op)
 
+    def optimize_COND_CALL_VALUE_PURE(self, op):
+        arg = op.getarg(0)
+        val = self.getvalue(arg)
+        if val.is_constant():
+            if val.box.same_constant(CONST_0):
+                self.last_emitted_operation = REMOVED
+                self.make_equal_to(op.result, self.getvalue(op.getarg(1)))
+                return
+            op = op.copy_and_change(rop.CALL, args=op.getarglist()[2:])
+        else:
+            op = op.copy_and_change(rop.COND_CALL_VALUE,
+                                    args=op.getarglist()[2:])
+        self.emit_operation(op)
+
     def _optimize_nullness(self, op, box, expect_nonnull):
         value = self.getvalue(box)
         if value.is_nonnull():
diff --git a/rpython/jit/metainterp/optimizeopt/simplify.py b/rpython/jit/metainterp/optimizeopt/simplify.py
--- a/rpython/jit/metainterp/optimizeopt/simplify.py
+++ b/rpython/jit/metainterp/optimizeopt/simplify.py
@@ -19,6 +19,11 @@
         self.emit_operation(ResOperation(rop.CALL, args, op.result,
                                          op.getdescr()))
 
+    def optimize_COND_CALL_VALUE_PURE(self, op):
+        args = op.getarglist()
+        self.emit_operation(ResOperation(rop.COND_CALL_VALUE, args, op.result,
+                                         op.getdescr()))
+
     def optimize_CALL_LOOPINVARIANT(self, op):
         op = op.copy_and_change(rop.CALL)
         self.emit_operation(op)
diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -1538,6 +1538,8 @@
             return   # so that the heapcache can keep argboxes virtual
         allboxes = self._build_allboxes(funcbox, argboxes, descr)
         effectinfo = descr.get_extra_info()
+        assert not effectinfo.check_is_elidable()
+        # XXX if the above assert fails, improve support for elidable COND_CALL
         assert not effectinfo.check_forces_virtual_or_virtualizable()
         exc = effectinfo.check_can_raise()
         pure = effectinfo.check_is_elidable()
@@ -1551,10 +1553,14 @@
         allboxes = self._build_allboxes(funcbox, argboxes, descr)
         effectinfo = descr.get_extra_info()
         assert not effectinfo.check_forces_virtual_or_virtualizable()
+        elidable = effectinfo.check_is_elidable()
         exc = effectinfo.check_can_raise()
         pure = effectinfo.check_is_elidable()
-        return self.execute_varargs(rop.COND_CALL_VALUE, [condbox, defbox] +
-                                    allboxes,
+        if elidable:
+            opnum = rop.COND_CALL_VALUE_PURE
+        else:
+            opnum = rop.COND_CALL_VALUE
+        return self.execute_varargs(opnum, [condbox, defbox] + allboxes,
                                     descr, exc, pure)
 
     def _do_jit_force_virtual(self, allboxes, descr, pc):
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -543,6 +543,7 @@
     'CALL_LOOPINVARIANT/*d',
     'CALL_RELEASE_GIL/*d',  # release the GIL and "close the stack" for asmgcc
     'CALL_PURE/*d',             # removed before it's passed to the backend
+    'COND_CALL_VALUE_PURE/*d',
     'CALL_MALLOC_GC/*d',      # like CALL, but NULL => propagate MemoryError
     'CALL_MALLOC_NURSERY/1',  # nursery malloc, const number of bytes, zeroed
     'CALL_MALLOC_NURSERY_VARSIZE/3d',
diff --git a/rpython/jit/metainterp/test/test_string.py b/rpython/jit/metainterp/test/test_string.py
--- a/rpython/jit/metainterp/test/test_string.py
+++ b/rpython/jit/metainterp/test/test_string.py
@@ -943,3 +943,7 @@
         self.meta_interp(f, [222, 3333])
         self.check_simple_loop({'guard_true': 1, 'int_add': 1,
                                 'int_lt': 1, 'jump': 1})
+
+    def test_string_hash(self):
+        jitdriver = JitDriver(greens = [], reds = [])
+        pass
diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -358,6 +358,7 @@
         return b
 
     @staticmethod
+    @jit.elidable
     def _ll_strhash(s):
         x = _hash_string(s.chars)
         if x == 0:
@@ -367,7 +368,6 @@
 
     @staticmethod
     def ll_strhash(s):
-        # XXX bring back elidable
         # unlike CPython, there is no reason to avoid to return -1
         # but our malloc initializes the memory to zero, so we use zero as the
         # special non-computed-yet value.


More information about the pypy-commit mailing list