]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
enable coalescing of the destination and source values of a copy operation in
authorAleksey Demakov <ademakov@gmail.com>
Wed, 18 Oct 2006 07:58:54 +0000 (07:58 +0000)
committerAleksey Demakov <ademakov@gmail.com>
Wed, 18 Oct 2006 07:58:54 +0000 (07:58 +0000)
a single register;
tag x86 copy rules with the "copy" keyword;
use separate destination register for x86 trunc rules;

ChangeLog
jit/jit-reg-alloc.c
jit/jit-rules-x86.ins

index 7a269e5109f13ee136b22c196cbb4119b55531e5..109fc9d9399c7eed8c19ec6314d1c9749d95daea 100644 (file)
--- a/ChangeLog
+++ b/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): 
index d0bf074457a0e2fae7edc160095edd1f54477483..9bae2bfaf6b21483d083f21fea517f0cdada07e6 100644 (file)
@@ -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;
index 84ba026bb313da88c90971174ce7afe759d08c7f..f1f97f5c0d5e9e8db4e71f1f930f032ef598f75c 100644 (file)
  * 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