Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit