+2008-05-08 Aleksey Demakov <ademakov@gmail.com>
+
+ * 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 <ktreichel@web.de>
* jit/jit-reg-alloc.c (_jit_regs_set_outgoing): Set the outgoing
_jit_regs_set_incoming
(gen, (int)jit_value_get_nint_constant(insn->value2),
insn->value1);
+ _jit_gen_insn(gen, func, block, insn);
}
break;
#endif
/*@
* @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
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
_jit_gen_load_value(gen, reg, other_reg, value);
}
+
jit_reg_set_used(gen->inhibit, reg);
if(other_reg >= 0)
{
* 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);
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);
* 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