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