[pypy-commit] pypy default: Another case of @jit.call_shortcut: tests that are directly "if x is not

arigo pypy.commits at gmail.com
Sat Nov 19 14:01:09 EST 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r88484:61f7052c3e44
Date: 2016-11-19 19:10 +0000
http://bitbucket.org/pypy/pypy/changeset/61f7052c3e44/

Log:	Another case of @jit.call_shortcut: tests that are directly "if x is
	not None: return x" or "if x != 0: return x"

diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -613,8 +613,11 @@
             return
         cs = effectinfo.call_shortcut
         ptr_box = op.getarg(1 + cs.argnum)
-        value_box = self.emit_getfield(ptr_box, descr=cs.fielddescr,
-                                       raw=(ptr_box.type == 'i'))
+        if cs.fielddescr is not None:
+            value_box = self.emit_getfield(ptr_box, descr=cs.fielddescr,
+                                           raw=(ptr_box.type == 'i'))
+        else:
+            value_box = ptr_box
         self.replace_op_with(op, ResOperation(cond_call_opnum,
                                               [value_box] + op.getarglist(),
                                               descr=descr))
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -88,6 +88,13 @@
         call_shortcut_descr = get_call_descr(self.gc_ll_descr,
             [lltype.Ptr(T)], lltype.Signed,
             effectinfo)
+        call_shortcut_2 = CallShortcut(0, None)
+        effectinfo_2 = EffectInfo(None, None, None, None, None, None,
+                                EffectInfo.EF_RANDOM_EFFECTS,
+                                call_shortcut=call_shortcut_2)
+        call_shortcut_descr_2 = get_call_descr(self.gc_ll_descr,
+            [lltype.Signed], lltype.Signed,
+            effectinfo_2)
         #
         A = lltype.GcArray(lltype.Signed)
         adescr = get_array_descr(self.gc_ll_descr, A)
@@ -1451,3 +1458,14 @@
             i1 = cond_call_value_i(i2, 123, p0, descr=call_shortcut_descr)
             jump(i1)
         """)
+
+    def test_handle_call_shortcut_2(self):
+        self.check_rewrite("""
+            [i0]
+            i1 = call_i(123, i0, descr=call_shortcut_descr_2)
+            jump(i1)
+        """, """
+            [i0]
+            i1 = cond_call_value_i(i0, 123, i0, descr=call_shortcut_descr_2)
+            jump(i1)
+        """)
diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py
--- a/rpython/jit/codewriter/call.py
+++ b/rpython/jit/codewriter/call.py
@@ -388,15 +388,23 @@
                    return y.field          if r: return r
         """
         block = graph.startblock
-        if len(block.operations) == 0:
-            return
-        op = block.operations[0]
-        if op.opname != 'getfield':
-            return
-        [v_inst, c_fieldname] = op.args
+        operations = block.operations
+        c_fieldname = None
+        if not operations:
+            v_inst = v_result = block.exitswitch
+        else:
+            op = operations[0]
+            if len(op.args) == 0:
+                return
+            if op.opname != 'getfield':  # check for this form:
+                v_inst = op.args[0]      #     if y is not None;
+                v_result = v_inst        #          return y
+            else:
+                operations = operations[1:]
+                [v_inst, c_fieldname] = op.args
+                v_result = op.result
         if not isinstance(v_inst, Variable):
             return
-        v_result = op.result
         if v_result.concretetype != graph.getreturnvar().concretetype:
             return
         if v_result.concretetype == lltype.Void:
@@ -409,7 +417,7 @@
         PSTRUCT = v_inst.concretetype
         v_check = v_result
         fastcase = True
-        for op in block.operations[1:]:
+        for op in operations:
             if (op.opname in ('int_is_true', 'ptr_nonzero', 'same_as')
                     and v_check is op.args[0]):
                 v_check = op.result
@@ -439,5 +447,8 @@
         if not link.target.is_final_block():
             return
 
-        fielddescr = self.cpu.fielddescrof(PSTRUCT.TO, c_fieldname.value)
+        if c_fieldname is not None:
+            fielddescr = self.cpu.fielddescrof(PSTRUCT.TO, c_fieldname.value)
+        else:
+            fielddescr = None
         return CallShortcut(argnum, fielddescr)
diff --git a/rpython/jit/codewriter/test/test_call.py b/rpython/jit/codewriter/test/test_call.py
--- a/rpython/jit/codewriter/test/test_call.py
+++ b/rpython/jit/codewriter/test/test_call.py
@@ -424,6 +424,21 @@
             r = b.foobar = 123
         return r
 
+    def f6(b):
+        if b is not None:
+            return b
+        return B()
+
+    def f7(c, a):
+        if a:
+            return a
+        return 123
+
+    def b_or_none(c):
+        if c > 15:
+            return B()
+        return None
+
     def f(a, c):
         b = B()
         f1(a, b, c)
@@ -432,6 +447,8 @@
         r = lltype.malloc(RAW, flavor='raw')
         f4(r)
         f5(b)
+        f6(b_or_none(c))
+        f7(c, a)
 
     rtyper = support.annotate(f, [10, 20])
     f1_graph = rtyper.annotator.translator._graphof(f1)
@@ -444,6 +461,10 @@
     assert cc.find_call_shortcut(f4_graph) == CallShortcut(0, "xdescr")
     f5_graph = rtyper.annotator.translator._graphof(f5)
     assert cc.find_call_shortcut(f5_graph) == CallShortcut(0, "foobardescr")
+    f6_graph = rtyper.annotator.translator._graphof(f6)
+    assert cc.find_call_shortcut(f6_graph) == CallShortcut(0, None)
+    f7_graph = rtyper.annotator.translator._graphof(f7)
+    assert cc.find_call_shortcut(f7_graph) == CallShortcut(1, None)
 
 def test_cant_find_call_shortcut():
     from rpython.jit.backend.llgraph.runner import LLGraphCPU


More information about the pypy-commit mailing list