From: Aleksey Demakov Date: Wed, 18 Oct 2006 07:58:54 +0000 (+0000) Subject: enable coalescing of the destination and source values of a copy operation in X-Git-Tag: before.move.to.git~184 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=26e815755451d4ef4b437dfdd409e406dd77dbee;p=francis%2Flibjit.git enable coalescing of the destination and source values of a copy operation in a single register; tag x86 copy rules with the "copy" keyword; use separate destination register for x86 trunc rules; --- diff --git a/ChangeLog b/ChangeLog index 7a269e5..109fc9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2006-10-18 Aleksey Demakov + + * jit/jit-reg-alloc.c (clobbers_register, bind_value): enable + coalescing of the destination value of a copy operation with the + source value in a single register. + + * jit/jit-rules-x86.ins: tag COPY rules with the "copy" keyword + and change patterns of TRUNC rules to have a separate destination + register. + 2006-10-16 Aleksey Demakov * jit/jit-interp.h, jit/jit-interp.c (_jit_run_function): diff --git a/jit/jit-reg-alloc.c b/jit/jit-reg-alloc.c index d0bf074..9bae2bf 100644 --- a/jit/jit-reg-alloc.c +++ b/jit/jit-reg-alloc.c @@ -236,10 +236,8 @@ are_values_equal(_jit_regdesc_t *desc1, _jit_regdesc_t *desc2) * might seem that there is no chance to find any dead value on the current * instruction. However if the value is used by the current instruction both * as the input and output then it was alive after the last instruction and - * hence was not freed. Also the old allocator might sometimes leave a dead - * value in the register and as of this writing the old allocator is still - * used by some rules. And just in case if some dead value may creep through - * the new allocator... + * hence was not freed. And just in case if some dead values may creep through + * the allocator's checks... */ static int value_usage(_jit_regs_t *regs, jit_value_t value) @@ -408,6 +406,20 @@ clobbers_register(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg, int else if(index == 0) { /* this is the output value of a binary or unary op */ + + /* special case: a copy operation. Check if we could coalesce + the destination value with the source. */ + if(regs->copy + && regs->descs[1].value + && regs->descs[1].value->in_register + && regs->descs[1].value->reg == reg + && ((regs->descs[0].value->in_register && regs->descs[0].value->reg == reg) + || gen->contents[reg].num_values < JIT_MAX_REG_VALUES + || !(regs->descs[1].used || regs->descs[1].live))) + { + return CLOBBER_NONE; + } + flags = CLOBBER_NONE; if(is_register_alive(gen, regs, reg)) { @@ -419,6 +431,10 @@ clobbers_register(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg, int } return flags; } + else if(regs->copy) + { + flags = CLOBBER_NONE; + } else if(regs->on_stack && !regs->no_pop) { /* this is a binary or unary stack op -- the input value @@ -586,7 +602,7 @@ set_regdesc_flags(jit_gencode_t gen, _jit_regs_t *regs, int index) return 1; } - /* Find the registers the value is already in (if any). */ + /* Find the register the value is already in (if any). */ if(desc->value->in_register) { reg = desc->value->reg; @@ -733,14 +749,7 @@ set_regdesc_flags(jit_gencode_t gen, _jit_regs_t *regs, int index) } else if(desc->load) { - if(desc->used) - { - if(clobber_input) - { - desc->kill = 1; - } - } - else + if(!desc->used || clobber_input) { desc->kill = 1; } @@ -1596,8 +1605,8 @@ bind_value(jit_gencode_t gen, jit_value_t value, int reg, int other_reg, int sti still_in_frame = 0; } - gen->contents[reg].values[0] = value; - gen->contents[reg].num_values = 1; + gen->contents[reg].values[gen->contents[reg].num_values] = value; + ++(gen->contents[reg].num_values); gen->contents[reg].age = gen->current_age; gen->contents[reg].used_for_temp = 0; gen->contents[reg].is_long_end = 0; diff --git a/jit/jit-rules-x86.ins b/jit/jit-rules-x86.ins index 84ba026..f1f97f5 100644 --- a/jit/jit-rules-x86.ins +++ b/jit/jit-rules-x86.ins @@ -22,27 +22,27 @@ * Conversion opcodes. */ -JIT_OP_TRUNC_SBYTE: unary - [reg("eax"|"ecx"|"edx"|"ebx")] -> { - x86_widen_reg(inst, $1, $1, 1, 0); +JIT_OP_TRUNC_SBYTE: + [=reg, reg("eax"|"ecx"|"edx"|"ebx")] -> { + x86_widen_reg(inst, $1, $2, 1, 0); } -JIT_OP_TRUNC_UBYTE: unary - [reg("eax"|"ecx"|"edx"|"ebx")] -> { - x86_widen_reg(inst, $1, $1, 0, 0); +JIT_OP_TRUNC_UBYTE: + [=reg, reg("eax"|"ecx"|"edx"|"ebx")] -> { + x86_widen_reg(inst, $1, $2, 0, 0); } -JIT_OP_TRUNC_SHORT: unary - [reg] -> { - x86_widen_reg(inst, $1, $1, 1, 1); +JIT_OP_TRUNC_SHORT: + [=reg, reg] -> { + x86_widen_reg(inst, $1, $2, 1, 1); } -JIT_OP_TRUNC_USHORT: unary - [reg] -> { - x86_widen_reg(inst, $1, $1, 0, 1); +JIT_OP_TRUNC_USHORT: + [=reg, reg] -> { + x86_widen_reg(inst, $1, $2, 0, 1); } -JIT_OP_CHECK_SBYTE: unary, more_space +JIT_OP_CHECK_SBYTE: more_space [reg] -> { unsigned char *patch1; unsigned char *patch2; @@ -57,7 +57,7 @@ JIT_OP_CHECK_SBYTE: unary, more_space x86_patch(patch2, inst); } -JIT_OP_CHECK_UBYTE: unary, more_space +JIT_OP_CHECK_UBYTE: more_space [reg] -> { unsigned char *patch1; x86_alu_reg_imm(inst, X86_CMP, $1, 256); @@ -67,7 +67,7 @@ JIT_OP_CHECK_UBYTE: unary, more_space x86_patch(patch1, inst); } -JIT_OP_CHECK_SHORT: unary, more_space +JIT_OP_CHECK_SHORT: more_space [reg] -> { unsigned char *patch1; unsigned char *patch2; @@ -82,7 +82,7 @@ JIT_OP_CHECK_SHORT: unary, more_space x86_patch(patch2, inst); } -JIT_OP_CHECK_USHORT: unary, more_space +JIT_OP_CHECK_USHORT: more_space [reg] -> { unsigned char *patch1; x86_alu_reg_imm(inst, X86_CMP, $1, 65536); @@ -92,7 +92,7 @@ JIT_OP_CHECK_USHORT: unary, more_space x86_patch(patch1, inst); } -JIT_OP_CHECK_INT, JIT_OP_CHECK_UINT: unary, more_space +JIT_OP_CHECK_INT, JIT_OP_CHECK_UINT: copy, more_space [reg] -> { unsigned char *patch1; x86_alu_reg_imm(inst, X86_CMP, $1, 0); @@ -101,7 +101,7 @@ JIT_OP_CHECK_INT, JIT_OP_CHECK_UINT: unary, more_space inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch1, inst); } - + JIT_OP_LOW_WORD: [=reg, imm] -> { jit_uint value = ((jit_uint *)($2))[0]; @@ -222,7 +222,7 @@ JIT_OP_NFLOAT_TO_FLOAT64: stack x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_float64)); } -JIT_OP_FLOAT32_TO_NFLOAT, JIT_OP_FLOAT64_TO_NFLOAT: unary, stack +JIT_OP_FLOAT32_TO_NFLOAT, JIT_OP_FLOAT64_TO_NFLOAT: copy, stack [freg] -> { /* Nothing to do: loading the value onto the FP stack is sufficient */ } @@ -1662,31 +1662,31 @@ JIT_OP_ADDRESS_OF_LABEL: * Data manipulation. */ -JIT_OP_COPY_LOAD_SBYTE: unary +JIT_OP_COPY_LOAD_SBYTE: copy [reg] -> {} -JIT_OP_COPY_LOAD_UBYTE: unary +JIT_OP_COPY_LOAD_UBYTE: copy [reg] -> {} -JIT_OP_COPY_LOAD_SHORT: unary +JIT_OP_COPY_LOAD_SHORT: copy [reg] -> {} -JIT_OP_COPY_LOAD_USHORT: unary +JIT_OP_COPY_LOAD_USHORT: copy [reg] -> {} -JIT_OP_COPY_INT: unary +JIT_OP_COPY_INT: copy [reg] -> {} -JIT_OP_COPY_LONG: unary +JIT_OP_COPY_LONG: copy [lreg] -> {} -JIT_OP_COPY_FLOAT32: unary, stack +JIT_OP_COPY_FLOAT32: copy, stack [freg] -> {} -JIT_OP_COPY_FLOAT64: unary, stack +JIT_OP_COPY_FLOAT64: copy, stack [freg] -> {} -JIT_OP_COPY_NFLOAT: unary, stack +JIT_OP_COPY_NFLOAT: copy, stack [freg] -> {} JIT_OP_COPY_STRUCT: manual, spill_before