Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit