Author: Armin Rigo <[email protected]>
Branch: conditional_call_value_3
Changeset: r87023:503727324fab
Date: 2016-09-12 11:15 +0200
http://bitbucket.org/pypy/pypy/changeset/503727324fab/
Log: Implement COND_CALL_VALUE (code copied from
conditional_call_value_2)
diff --git a/rpython/jit/backend/x86/assembler.py
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -174,8 +174,8 @@
# copy registers to the frame, with the exception of the
# 'cond_call_register_arguments' and eax, because these have already
# been saved by the caller. Note that this is not symmetrical:
- # these 5 registers are saved by the caller but restored here at
- # the end of this function.
+ # these 5 registers are saved by the caller but 4 of them are
+ # restored here at the end of this function.
self._push_all_regs_to_frame(mc, cond_call_register_arguments + [eax],
supports_floats, callee_only)
# the caller already did push_gcmap(store=True)
@@ -198,7 +198,7 @@
mc.ADD(esp, imm(WORD * 7))
self.set_extra_stack_depth(mc, 0)
self.pop_gcmap(mc) # cancel the push_gcmap(store=True) in the caller
- self._pop_all_regs_from_frame(mc, [], supports_floats, callee_only)
+ self._pop_all_regs_from_frame(mc, [eax], supports_floats, callee_only)
mc.RET()
return mc.materialize(self.cpu, [])
@@ -1703,7 +1703,8 @@
self.implement_guard(guard_token)
# If the previous operation was a COND_CALL, overwrite its conditional
# jump to jump over this GUARD_NO_EXCEPTION as well, if we can
- if self._find_nearby_operation(-1).getopnum() == rop.COND_CALL:
+ if self._find_nearby_operation(-1).getopnum() in (
+ rop.COND_CALL, rop.COND_CALL_VALUE_I, rop.COND_CALL_VALUE_R):
jmp_adr = self.previous_cond_call_jcond
offset = self.mc.get_relative_pos() - jmp_adr
if offset <= 127:
@@ -2381,7 +2382,7 @@
def label(self):
self._check_frame_depth_debug(self.mc)
- def cond_call(self, op, gcmap, imm_func, arglocs):
+ def cond_call(self, op, gcmap, imm_func, arglocs, resloc=None):
assert self.guard_success_cc >= 0
self.mc.J_il8(rx86.invert_condition(self.guard_success_cc), 0)
# patched later
@@ -2394,11 +2395,14 @@
# plus the register 'eax'
base_ofs = self.cpu.get_baseofs_of_frame_field()
should_be_saved = self._regalloc.rm.reg_bindings.values()
+ restore_eax = False
for gpr in cond_call_register_arguments + [eax]:
- if gpr not in should_be_saved:
+ if gpr not in should_be_saved or gpr is resloc:
continue
v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
self.mc.MOV_br(v * WORD + base_ofs, gpr.value)
+ if gpr is eax:
+ restore_eax = True
#
# load the 0-to-4 arguments into these registers
from rpython.jit.backend.x86.jump import remap_frame_layout
@@ -2422,8 +2426,16 @@
floats = True
cond_call_adr = self.cond_call_slowpath[floats * 2 + callee_only]
self.mc.CALL(imm(follow_jump(cond_call_adr)))
+ # if this is a COND_CALL_VALUE, we need to move the result in place
+ if resloc is not None and resloc is not eax:
+ self.mc.MOV(resloc, eax)
# restoring the registers saved above, and doing pop_gcmap(), is left
- # to the cond_call_slowpath helper. We never have any result value.
+ # to the cond_call_slowpath helper. We must only restore eax, if
+ # needed.
+ if restore_eax:
+ v = gpr_reg_mgr_cls.all_reg_indexes[eax.value]
+ self.mc.MOV_rb(eax.value, v * WORD + base_ofs)
+ #
offset = self.mc.get_relative_pos() - jmp_adr
assert 0 < offset <= 127
self.mc.overwrite(jmp_adr-1, chr(offset))
diff --git a/rpython/jit/backend/x86/regalloc.py
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -938,16 +938,28 @@
self.rm.force_spill_var(box)
assert box not in self.rm.reg_bindings
#
- assert op.type == 'v'
args = op.getarglist()
assert 2 <= len(args) <= 4 + 2 # maximum 4 arguments
- v = args[1]
- assert isinstance(v, Const)
- imm_func = self.rm.convert_to_imm(v)
+ v_func = args[1]
+ assert isinstance(v_func, Const)
+ imm_func = self.rm.convert_to_imm(v_func)
arglocs = [self.loc(args[i]) for i in range(2, len(args))]
gcmap = self.get_gcmap()
- self.load_condition_into_cc(op.getarg(0))
- self.assembler.cond_call(op, gcmap, imm_func, arglocs)
+ if op.type == 'v':
+ # a plain COND_CALL
+ self.load_condition_into_cc(op.getarg(0))
+ resloc = None
+ else:
+ # COND_CALL_VALUE_I/R
+ condvalue_loc = self.loc(args[0])
+ assert not isinstance(condvalue_loc, ImmedLoc)
+ self.assembler.test_location(condvalue_loc)
+ self.assembler.guard_success_cc = rx86.Conditions['Z']
+ resloc = self.rm.force_result_in_reg(op, args[0])
+ self.assembler.cond_call(op, gcmap, imm_func, arglocs, resloc)
+
+ consider_cond_call_value_i = consider_cond_call
+ consider_cond_call_value_r = consider_cond_call
def consider_call_malloc_nursery(self, op):
size_box = op.getarg(0)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit