Author: Armin Rigo <ar...@tunes.org>
Branch: conditional_call_value_2
Changeset: r86990:5701981db5d8
Date: 2016-09-11 10:56 +0200
http://bitbucket.org/pypy/pypy/changeset/5701981db5d8/

Log:    in-progress

diff --git a/rpython/jit/codewriter/jtransform.py 
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -364,7 +364,7 @@
         return getattr(self, 'handle_%s_indirect_call' % kind)(op)
 
     def rewrite_call(self, op, namebase, initialargs, args=None,
-                     calldescr=None):
+                     calldescr=None, forced_ir=False):
         """Turn 'i0 = direct_call(fn, i1, i2, ref1, ref2)'
            into 'i0 = xxx_call_ir_i(fn, descr, [i1,i2], [ref1,ref2])'.
            The name is one of '{residual,direct}_call_{r,ir,irf}_{i,r,f,v}'."""
@@ -374,7 +374,7 @@
         lst_i, lst_r, lst_f = self.make_three_lists(args)
         reskind = getkind(op.result.concretetype)[0]
         if lst_f or reskind == 'f': kinds = 'irf'
-        elif lst_i: kinds = 'ir'
+        elif lst_i or forced_ir: kinds = 'ir'
         else: kinds = 'r'
         sublists = []
         if 'i' in kinds: sublists.append(lst_i)
@@ -1564,20 +1564,19 @@
             return []
         return getattr(self, 'handle_jit_marker__%s' % key)(op, jitdriver)
 
-    def rewrite_op_jit_conditional_call(self, op):
-        have_floats = False
+    def rewrite_op_jit_conditional_call_value(self, op):
+        have_floats = (getkind(op.result.concretetype) == 'float')
         for arg in op.args:
             if getkind(arg.concretetype) == 'float':
                 have_floats = True
-                break
-        if len(op.args) > 4 + 2 or have_floats:
+        if len(op.args) > 4 + 3 or have_floats:
             raise Exception("Conditional call does not support floats or more 
than 4 arguments")
-        callop = SpaceOperation('direct_call', op.args[1:], op.result)
+        callop = SpaceOperation('direct_call', op.args[2:], op.result)
         calldescr = self.callcontrol.getcalldescr(callop)
         assert not 
calldescr.get_extra_info().check_forces_virtual_or_virtualizable()
         op1 = self.rewrite_call(op, 'conditional_call',
-                                op.args[:2], args=op.args[2:],
-                                calldescr=calldescr)
+                                op.args[:3], args=op.args[3:],
+                                calldescr=calldescr, forced_ir=True)
         if self.callcontrol.calldescr_canraise(calldescr):
             op1 = [op1, SpaceOperation('-live-', [], None)]
         return op1
diff --git a/rpython/jit/metainterp/blackhole.py 
b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -1199,29 +1199,26 @@
     def bhimpl_residual_call_irf_v(cpu, func, args_i,args_r,args_f,calldescr):
         return cpu.bh_call_v(func, args_i, args_r, args_f, calldescr)
 
-    # conditional calls - note that they cannot return stuff
-    @arguments("cpu", "i", "i", "I", "d")
-    def bhimpl_conditional_call_i_v(cpu, condition, func, args_i, calldescr):
-        if condition:
-            cpu.bh_call_v(func, args_i, None, None, calldescr)
+    @arguments("cpu", "i", "i", "I", "R", "d", returns="i")
+    def bhimpl_conditional_call_ir_i(cpu, value, special_constant,
+                                     func, args_i, args_r, calldescr):
+        if value == special_constant:
+            value = cpu.bh_call_i(func, args_i, args_r, None, calldescr)
+        return value
 
-    @arguments("cpu", "i", "i", "R", "d")
-    def bhimpl_conditional_call_r_v(cpu, condition, func, args_r, calldescr):
-        if condition:
-            cpu.bh_call_v(func, None, args_r, None, calldescr)
+    @arguments("cpu", "r", "r", "I", "R", "d", returns="r")
+    def bhimpl_conditional_call_ir_r(cpu, value, special_constant,
+                                     func, args_i, args_r, calldescr):
+        if value == special_constant:
+            value = cpu.bh_call_r(func, args_i, args_r, None, calldescr)
+        return value
 
-    @arguments("cpu", "i", "i", "I", "R", "d")
-    def bhimpl_conditional_call_ir_v(cpu, condition, func, args_i, args_r,
-                                     calldescr):
-        if condition:
+    @arguments("cpu", "r", "r", "I", "R", "d")
+    def bhimpl_conditional_call_ir_v(cpu, value, special_constant,
+                                     func, args_i, args_r, calldescr):
+        if value == special_constant:
             cpu.bh_call_v(func, args_i, args_r, None, calldescr)
 
-    @arguments("cpu", "i", "i", "I", "R", "F", "d")
-    def bhimpl_conditional_call_irf_v(cpu, condition, func, args_i, args_r,
-                                      args_f, calldescr):
-        if condition:
-            cpu.bh_call_v(func, args_i, args_r, args_f, calldescr)
-
     @arguments("cpu", "j", "R", returns="i")
     def bhimpl_inline_call_r_i(cpu, jitcode, args_r):
         return cpu.bh_call_i(jitcode.get_fnaddr_as_int(),
diff --git a/rpython/jit/metainterp/executor.py 
b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -96,10 +96,26 @@
 do_call_may_force_f = do_call_f
 do_call_may_force_n = do_call_n
 
-def do_cond_call(cpu, metainterp, argboxes, descr):
-    condbox = argboxes[0]
-    if condbox.getint():
-        do_call_n(cpu, metainterp, argboxes[1:], descr)
+def do_cond_call_i(cpu, metainterp, argboxes, descr):
+    cond = argboxes[0].getint()
+    specialval = argboxes[1].getint()
+    if cond == specialval:
+        return do_call_i(cpu, metainterp, argboxes[2:], descr)
+    return cond
+
+def do_cond_call_r(cpu, metainterp, argboxes, descr):
+    cond = argboxes[0].getref_base()
+    specialval = argboxes[1].getref_base()
+    if cond == specialval:
+        return do_call_r(cpu, metainterp, argboxes[2:], descr)
+    return cond
+
+def do_cond_call_n(cpu, metainterp, argboxes, descr):
+    cond = argboxes[0].getint()
+    specialval = argboxes[1].getint()
+    assert specialval == 1       # cond_call_n is only used with that case
+    if cond == specialval:
+        do_call_n(cpu, metainterp, argboxes[2:], descr)
 
 def do_getarrayitem_gc_i(cpu, _, arraybox, indexbox, arraydescr):
     array = arraybox.getref_base()
diff --git a/rpython/jit/metainterp/heapcache.py 
b/rpython/jit/metainterp/heapcache.py
--- a/rpython/jit/metainterp/heapcache.py
+++ b/rpython/jit/metainterp/heapcache.py
@@ -271,7 +271,8 @@
             return
         if (OpHelpers.is_plain_call(opnum) or
             OpHelpers.is_call_loopinvariant(opnum) or
-            opnum == rop.COND_CALL):
+            opnum == rop.COND_CALL_I or
+            opnum == rop.COND_CALL_R):
             effectinfo = descr.get_extra_info()
             ef = effectinfo.extraeffect
             if (ef == effectinfo.EF_LOOPINVARIANT or
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
@@ -904,7 +904,8 @@
                                        history.CONST_NULL)
         funcbox = ConstInt(rffi.cast(lltype.Signed, vinfo.clear_vable_ptr))
         calldescr = vinfo.clear_vable_descr
-        self.execute_varargs(rop.COND_CALL, [condbox, funcbox, box],
+        self.execute_varargs(rop.COND_CALL_I, [condbox, history.CONST_TRUE,
+                                               funcbox, box],
                              calldescr, False, False)
 
     def _get_virtualizable_field_index(self, fielddescr):
@@ -1056,22 +1057,26 @@
     opimpl_residual_call_irf_f = _opimpl_residual_call3
     opimpl_residual_call_irf_v = _opimpl_residual_call3
 
-    @arguments("box", "box", "boxes", "descr", "orgpc")
-    def opimpl_conditional_call_i_v(self, condbox, funcbox, argboxes, 
calldescr,
-                                    pc):
-        self.do_conditional_call(condbox, funcbox, argboxes, calldescr, pc)
-
-    opimpl_conditional_call_r_v = opimpl_conditional_call_i_v
-
-    @arguments("box", "box", "boxes2", "descr", "orgpc")
-    def opimpl_conditional_call_ir_v(self, condbox, funcbox, argboxes,
-                                     calldescr, pc):
-        self.do_conditional_call(condbox, funcbox, argboxes, calldescr, pc)
-
-    @arguments("box", "box", "boxes3", "descr", "orgpc")
-    def opimpl_conditional_call_irf_v(self, condbox, funcbox, argboxes,
-                                      calldescr, pc):
-        self.do_conditional_call(condbox, funcbox, argboxes, calldescr, pc)
+    @arguments("box", "box", "box", "boxes2", "descr", "orgpc")
+    def opimpl_conditional_call_ir_i(self, condbox, specialvalbox,
+                                     funcbox, argboxes, calldescr, pc):
+        return self.do_conditional_call(condbox, specialvalbox,
+                                        funcbox, argboxes, calldescr, pc,
+                                        rop.COND_CALL_I)
+
+    @arguments("box", "box", "box", "boxes2", "descr", "orgpc")
+    def opimpl_conditional_call_ir_r(self, condbox, specialvalbox,
+                                     funcbox, argboxes, calldescr, pc):
+        return self.do_conditional_call(condbox, specialvalbox,
+                                        funcbox, argboxes, calldescr, pc,
+                                        rop.COND_CALL_R)
+
+    @arguments("box", "box", "box", "boxes2", "descr", "orgpc")
+    def opimpl_conditional_call_ir_v(self, condbox, specialvalbox,
+                                     funcbox, argboxes, calldescr, pc):
+        return self.do_conditional_call(condbox, specialvalbox,
+                                        funcbox, argboxes, calldescr, pc,
+                                        rop.COND_CALL_N)
 
     @arguments("int", "boxes3", "boxes3", "orgpc")
     def _opimpl_recursive_call(self, jdindex, greenboxes, redboxes, pc):
@@ -1724,16 +1729,19 @@
             else:
                 assert False
 
-    def do_conditional_call(self, condbox, funcbox, argboxes, descr, pc):
-        if isinstance(condbox, ConstInt) and condbox.value == 0:
-            return   # so that the heapcache can keep argboxes virtual
+    def do_conditional_call(self, condbox, specialvalbox,
+                            funcbox, argboxes, descr, pc, rop_num):
+        if (isinstance(condbox, Const) and
+                not condbox.same_constant(specialvalbox)):
+            return condbox  # so that the heapcache can keep argboxes virtual
         allboxes = self._build_allboxes(funcbox, argboxes, descr)
         effectinfo = descr.get_extra_info()
         assert not effectinfo.check_forces_virtual_or_virtualizable()
         exc = effectinfo.check_can_raise()
         pure = effectinfo.check_is_elidable()
-        return self.execute_varargs(rop.COND_CALL, [condbox] + allboxes, descr,
-                                    exc, pure)
+        return self.execute_varargs(rop_num,
+                                    [condbox, specialvalbox] + allboxes,
+                                    descr, exc, pure)
 
     def _do_jit_force_virtual(self, allboxes, descr, pc):
         assert len(allboxes) == 2
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
@@ -1149,7 +1149,7 @@
     '_CANRAISE_FIRST', # ----- start of can_raise operations -----
     '_CALL_FIRST',
     'CALL/*d/rfin',
-    'COND_CALL/*d/n',
+    'COND_CALL/*d/rin',
     # a conditional call, with first argument as a condition
     'CALL_ASSEMBLER/*d/rfin',  # call already compiled assembler
     'CALL_MAY_FORCE/*d/rfin',
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -1178,13 +1178,15 @@
         hop.exception_is_here()
         return hop.gendirectcall(ll_record_exact_class, v_inst, v_cls)
 
+def _jit_conditional_call(value, ignored, function, *args):
+    """NOT_RPYTHON"""
 def _jit_conditional_call_value(value, special_constant, function, *args):
     """NOT_RPYTHON"""
 
 @specialize.call_location()
 def conditional_call(condition, function, *args):
     if we_are_jitted():
-        _jit_conditional_call_value(condition, True, function, *args)
+        _jit_conditional_call(condition, True, function, *args)
     else:
         if condition:
             function(*args)
@@ -1202,12 +1204,14 @@
 conditional_call_value._always_inline_ = True
 
 class ConditionalCallEntry(ExtRegistryEntry):
-    _about_ = _jit_conditional_call_value
+    _about_ = _jit_conditional_call_value, _jit_conditional_call
 
     def compute_result_annotation(self, *args_s):
+        from rpython.annotator import model as annmodel
         self.bookkeeper.emulate_pbc_call(self.bookkeeper.position_key,
                                          args_s[2], args_s[3:])
-        return args_s[0]
+        if self.instance is _jit_conditional_call_value:
+            return args_s[0]
 
     def specialize_call(self, hop):
         from rpython.rtyper.lltypesystem import lltype
@@ -1218,7 +1222,7 @@
                                                     hop.args_s[3:], 
hop.spaceop)
         hop.exception_is_here()
         return hop.genop('jit_conditional_call_value', args_v,
-                         resulttype=r_value)
+                         resulttype=hop.r_result)
 
 def enter_portal_frame(unique_id):
     """call this when starting to interpret a function. calling this is not
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to