Browse Source

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;
cache-refactoring
Aleksey Demakov 18 years ago
parent
commit
26e8157554
  1. 10
      ChangeLog
  2. 39
      jit/jit-reg-alloc.c
  3. 56
      jit/jit-rules-x86.ins

10
ChangeLog

@ -1,3 +1,13 @@
2006-10-18 Aleksey Demakov <ademakov@gmail.com>
* 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 <ademakov@gmail.com>
* jit/jit-interp.h, jit/jit-interp.c (_jit_run_function):

39
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;

56
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

Loading…
Cancel
Save