From: Aleksey Demakov Date: Thu, 8 May 2008 06:39:50 +0000 (+0000) Subject: let register allocator free unused values that result from JIT_OP_INCOMING_REG and... X-Git-Tag: before.move.to.git~78 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=cc01123c728e919298f8d4222c3fa2836bee9994;p=francis%2Flibjit.git let register allocator free unused values that result from JIT_OP_INCOMING_REG and JIT_OP_RETURN_REG instructions --- diff --git a/ChangeLog b/ChangeLog index 7dae313..c3581e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-05-08 Aleksey Demakov + + * jit/jit-rules-x86.ins: + * jit/jit-rules-x86-64.ins: + * jit/jit-function.c (compile_block): let register allocator see + JIT_OP_INCOMING_REG and JIT_OP_RETURN_REG instructions so it can + free unused values on these instructions rather than on the block + end. + + * jit/jit-reg-alloc.c (_jit_regs_set_incoming): it is not possible + to correctly spill the old register value at this point so do not + attempt this and do not promise this. + 2008-05-04 Klaus Treichel * jit/jit-reg-alloc.c (_jit_regs_set_outgoing): Set the outgoing diff --git a/jit/jit-function.c b/jit/jit-function.c index c34ada1..9df5f7a 100644 --- a/jit/jit-function.c +++ b/jit/jit-function.c @@ -532,6 +532,7 @@ static void compile_block(jit_gencode_t gen, jit_function_t func, _jit_regs_set_incoming (gen, (int)jit_value_get_nint_constant(insn->value2), insn->value1); + _jit_gen_insn(gen, func, block, insn); } break; #endif diff --git a/jit/jit-reg-alloc.c b/jit/jit-reg-alloc.c index d153f5d..1394aa4 100644 --- a/jit/jit-reg-alloc.c +++ b/jit/jit-reg-alloc.c @@ -2915,8 +2915,8 @@ _jit_regs_spill_all(jit_gencode_t gen) /*@ * @deftypefun void _jit_regs_set_incoming (jit_gencode_t gen, int reg, jit_value_t value) * Set pseudo register @code{reg} to record that it currently holds the - * contents of @code{value}. If the register was previously in use, - * then spill its value first. + * contents of @code{value}. The register must not contain any other + * live value at this point. * @end deftypefun @*/ void @@ -2934,12 +2934,18 @@ _jit_regs_set_incoming(jit_gencode_t gen, int reg, jit_value_t value) other_reg = -1; } + /* avd: It's too late to spill here, if there was any + value it is already cloberred by the incoming value. + So for correct code generation the register must be + free by now (spilled at some earlier point). */ +#if 0 /* Eject any values that are currently in the register */ spill_register(gen, reg); if(other_reg >= 0) { spill_register(gen, other_reg); } +#endif /* Record that the value is in "reg", but not in the frame */ #ifdef JIT_REG_STACK @@ -3018,6 +3024,7 @@ _jit_regs_set_outgoing(jit_gencode_t gen, int reg, jit_value_t value) _jit_gen_load_value(gen, reg, other_reg, value); } + jit_reg_set_used(gen->inhibit, reg); if(other_reg >= 0) { diff --git a/jit/jit-rules-x86-64.ins b/jit/jit-rules-x86-64.ins index 659e98f..f9b6489 100644 --- a/jit/jit-rules-x86-64.ins +++ b/jit/jit-rules-x86-64.ins @@ -263,6 +263,17 @@ JIT_OP_ADDRESS_OF: * Stack pushes and pops. */ +JIT_OP_INCOMING_REG, JIT_OP_RETURN_REG: note + [reg] -> { + /* + * This rule does nothing itself. Also at this point + * the value is supposed to be already in the register + * so the "reg" pattern does not load it either. But + * it allows the allocator to check the liveness flags + * and free the register if the value is dead. + */ + } + JIT_OP_PUSH_INT: note [imm] -> { x86_64_push_imm(inst, $1); @@ -428,11 +439,6 @@ JIT_OP_RETURN: inst = jump_to_epilog(gen, inst, block); } -JIT_OP_RETURN_REG: manual - [] -> { - /* Nothing to do here */; - } - JIT_OP_RETURN_INT: note [reg("rax")] -> { inst = jump_to_epilog(gen, inst, block); diff --git a/jit/jit-rules-x86.ins b/jit/jit-rules-x86.ins index 4861ffc..b1dfef3 100644 --- a/jit/jit-rules-x86.ins +++ b/jit/jit-rules-x86.ins @@ -1990,9 +1990,15 @@ JIT_OP_ADDRESS_OF: * Stack pushes and pops. */ -JIT_OP_RETURN_REG: manual - [] -> { - /* Nothing to do here */; +JIT_OP_INCOMING_REG, JIT_OP_RETURN_REG: note + [reg] -> { + /* + * This rule does nothing itself. Also at this point + * the value is supposed to be already in the register + * so the "reg" pattern does not load it either. But + * it allows the allocator to check the liveness flags + * and free the register if the value is dead. + */ } JIT_OP_PUSH_INT: note