Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r65781:caa2340430f2 Date: 2013-07-29 14:59 +0200 http://bitbucket.org/pypy/pypy/changeset/caa2340430f2/
Log: Fix the test and generate more efficient code. 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 @@ -14,7 +14,7 @@ from rpython.rlib.jit import AsmInfo from rpython.jit.backend.model import CompiledLoopToken from rpython.jit.backend.x86.regalloc import (RegAlloc, get_ebp_ofs, - gpr_reg_mgr_cls, xmm_reg_mgr_cls, _register_arguments) + gpr_reg_mgr_cls, xmm_reg_mgr_cls) from rpython.jit.backend.llsupport.regalloc import (get_scale, valid_addressing_size) from rpython.jit.backend.x86.arch import (FRAME_FIXED_SIZE, WORD, IS_X86_64, JITFRAME_FIXED_SIZE, IS_X86_32, @@ -154,7 +154,11 @@ come. """ mc = codebuf.MachineCodeBlockWrapper() - self._push_all_regs_to_frame(mc, [], supports_floats, callee_only) + # 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 + self._push_all_regs_to_frame(mc, cond_call_register_arguments + [eax], + supports_floats, callee_only) if IS_X86_64: mc.SUB(esp, imm(WORD)) self.set_extra_stack_depth(mc, 2 * WORD) @@ -164,7 +168,7 @@ mc.SUB(esp, imm(WORD * 7)) self.set_extra_stack_depth(mc, 8 * WORD) for i in range(4): - mc.MOV_sr(i * WORD, _register_arguments[i].value) + mc.MOV_sr(i * WORD, cond_call_register_arguments[i].value) mc.CALL(eax) if IS_X86_64: mc.ADD(esp, imm(WORD)) @@ -172,8 +176,7 @@ mc.ADD(esp, imm(WORD * 7)) self.set_extra_stack_depth(mc, 0) self._reload_frame_if_necessary(mc, align_stack=True) - self._pop_all_regs_from_frame(mc, [], supports_floats, - callee_only) + self._pop_all_regs_from_frame(mc, [], supports_floats, callee_only) mc.RET() return mc.materialize(self.cpu.asmmemmgr, []) @@ -1755,7 +1758,7 @@ regs = gpr_reg_mgr_cls.save_around_call_regs else: regs = gpr_reg_mgr_cls.all_regs - for i, gpr in enumerate(regs): + for gpr in regs: if gpr not in ignored_regs: v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value] mc.MOV_br(v * WORD + base_ofs, gpr.value) @@ -1777,7 +1780,7 @@ regs = gpr_reg_mgr_cls.save_around_call_regs else: regs = gpr_reg_mgr_cls.all_regs - for i, gpr in enumerate(regs): + for gpr in regs: if gpr not in ignored_regs: v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value] mc.MOV_rb(gpr.value, v * WORD + base_ofs) @@ -2161,11 +2164,29 @@ def label(self): self._check_frame_depth_debug(self.mc) - def cond_call(self, op, gcmap, cond_loc, call_loc): - self.mc.TEST(cond_loc, cond_loc) + def cond_call(self, op, gcmap, loc_cond, imm_func, arglocs): + self.mc.TEST(loc_cond, loc_cond) self.mc.J_il8(rx86.Conditions['Z'], 0) # patched later jmp_adr = self.mc.get_relative_pos() + # self.push_gcmap(self.mc, gcmap, store=True) + # + # first save away the 4 registers from 'cond_call_register_arguments' + # plus the register 'eax' + base_ofs = self.cpu.get_baseofs_of_frame_field() + for gpr in cond_call_register_arguments + [eax]: + v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value] + self.mc.MOV_br(v * WORD + base_ofs, gpr.value) + # + # load the 0-to-4 arguments into these registers + from rpython.jit.backend.x86.jump import remap_frame_layout + remap_frame_layout(self, arglocs, + cond_call_register_arguments[:len(arglocs)], eax) + # + # load the constant address of the function to call into eax + self.mc.MOV(eax, imm_func) + # + # figure out which variant of cond_call_slowpath to call, and call it callee_only = False floats = False if self._regalloc is not None: @@ -2348,5 +2369,7 @@ os.write(2, '[x86/asm] %s\n' % msg) raise NotImplementedError(msg) +cond_call_register_arguments = [edi, esi, edx, ecx] + class BridgeAlreadyCompiled(Exception): pass 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 @@ -119,8 +119,6 @@ for _i, _reg in enumerate(gpr_reg_mgr_cls.all_regs): gpr_reg_mgr_cls.all_reg_indexes[_reg.value] = _i -_register_arguments = [edi, esi, edx, ecx] - class RegAlloc(BaseRegalloc): @@ -803,21 +801,15 @@ def consider_cond_call(self, op): assert op.result is None args = op.getarglist() - assert 2 <= len(args) <= 4 + 2 - tmpbox = TempBox() - self.rm.force_allocate_reg(tmpbox, selected_reg=eax) + assert 2 <= len(args) <= 4 + 2 # maximum 4 arguments + loc_cond = self.make_sure_var_in_reg(args[0], args) v = args[1] assert isinstance(v, Const) - imm = self.rm.convert_to_imm(v) - self.assembler.regalloc_mov(imm, eax) - args_so_far = [tmpbox] - for i in range(2, len(args)): - reg = _register_arguments[i - 2] - self.make_sure_var_in_reg(args[i], args_so_far, selected_reg=reg) - args_so_far.append(args[i]) - loc_cond = self.make_sure_var_in_reg(args[0], args) - self.assembler.cond_call(op, self.get_gcmap([eax]), loc_cond, eax) - self.rm.possibly_free_var(tmpbox) + imm_func = self.rm.convert_to_imm(v) + arglocs = [self.loc(args[i]) for i in range(2, len(args))] + gcmap = self.get_gcmap() + self.rm.possibly_free_var(args[0]) + self.assembler.cond_call(op, gcmap, loc_cond, imm_func, arglocs) def consider_call_malloc_nursery(self, op): size_box = op.getarg(0) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit