From: Aleksey Demakov Date: Tue, 27 Jun 2006 15:03:11 +0000 (+0000) Subject: fix problem with relative instructions X-Git-Tag: before.move.to.git~229 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=f59c4502c240d73a057ab115fd605df1102a1928;p=francis%2Flibjit.git fix problem with relative instructions --- diff --git a/ChangeLog b/ChangeLog index 6958349..c5ca761 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2006-06-27 Aleksey Demakov + + * jit/jit-insn.c (accumulate_relative_offset): add function that + accumulates JIT_OP_ADD_RELATIVE offsets. + (jit_insn_store_relative, jit_insn_load_relative) + (jit_insn_add_relative): use accumulate_relative_offset() instead + of previous_relative() to find the offset from the original address + and do not replace the accumulated instructions with JIT_OP_NOP as + it was before. The old approach is problematic because it is unknown + at this point if the values we accumulated are dead or they will be + used by instructions added later. The deadcode elimination pass + removes unused values just as well but with enough knowledge to be + safe. The new code also does not move JIT_OP_ADDRESS_OF towards the + relative instructions that uses the address. Supposedly such move + may be used by the code generator as a hint. However currently the + code generator does not use such a hint. The old code is kept for + reference #ifdefed out. + 2006-06-17 Aleksey Demakov * jit/jit-reg-alloc.h, jit/jit-reg-alloc.c: implement support of the diff --git a/jit/jit-insn.c b/jit/jit-insn.c index 9e6d42f..85c2fed 100644 --- a/jit/jit-insn.c +++ b/jit/jit-insn.c @@ -1465,6 +1465,10 @@ int jit_insn_store(jit_function_t func, jit_value_t dest, jit_value_t value) return 1; } +#define ACCUMULATE_RELATIVE 1 + +#if !ACCUMULATE_RELATIVE + /* * Scan back through the current block, looking for a relative adjustment * that involves "value" as its destination. Returns NULL if no such @@ -1554,6 +1558,81 @@ static jit_insn_t previous_relative(jit_function_t func, jit_value_t value, return 0; } +#else + +static int +accumulate_relative_offset( + jit_function_t func, + jit_value_t value, + jit_nint offset, + jit_value_t *addrof_ptr, + jit_value_t *value_ptr, + jit_nint *offset_ptr) +{ + jit_insn_iter_t iter; + jit_insn_t insn; + + if(addrof_ptr) + { + *addrof_ptr = 0; + } + if(value_ptr) + { + *value_ptr = 0; + } + if(offset_ptr) + { + *offset_ptr = 0; + } + + jit_insn_iter_init_last(&iter, func->builder->current_block); + while((insn = jit_insn_iter_previous(&iter)) != 0) + { + if(!(value->is_temporary)) + { + break; + } + if(insn->dest != value) + { + continue; + } + if(insn->opcode == JIT_OP_ADDRESS_OF) + { + if(addrof_ptr) + { + *addrof_ptr = insn->value1; + } + break; + } + if(insn->opcode != JIT_OP_ADD_RELATIVE) + { + if((insn->flags & JIT_INSN_DEST_IS_VALUE) == 0) + { + /* This instruction modifies "value" in some way, + so it blocks any previous "add_relative" + instructions */ + return 0; + } + continue; + } + offset += jit_value_get_nint_constant(insn->value2); + value = insn->value1; + } + + if(value_ptr) + { + *value_ptr = value; + } + if(offset_ptr) + { + *offset_ptr = offset; + } + + return 1; +} + +#endif + /*@ * @deftypefun jit_value_t jit_insn_load_relative (jit_function_t func, jit_value_t value, jit_nint offset, jit_type_t type) * Load a value of the specified @code{type} from the effective address @@ -1564,8 +1643,14 @@ jit_value_t jit_insn_load_relative (jit_function_t func, jit_value_t value, jit_nint offset, jit_type_t type) { +#if ACCUMULATE_RELATIVE + jit_value_t addrof; + jit_value_t new_value; + jit_nint new_offset; +#else jit_insn_t insn; jit_insn_t addrof; +#endif if(!value) { return 0; @@ -1574,6 +1659,13 @@ jit_value_t jit_insn_load_relative { return 0; } +#if ACCUMULATE_RELATIVE + if(accumulate_relative_offset(func, value, offset, &addrof, &new_value, &new_offset)) + { + value = new_value; + offset = new_offset; + } +#else insn = previous_relative(func, value, &addrof); if(insn) { @@ -1602,6 +1694,7 @@ jit_value_t jit_insn_load_relative addrof->value2 = 0; } } +#endif return apply_binary (func, _jit_load_opcode(JIT_OP_LOAD_RELATIVE_SBYTE, type, 0, 0), value, jit_value_create_nint_constant(func, jit_type_nint, offset), type); @@ -1618,8 +1711,14 @@ int jit_insn_store_relative jit_nint offset, jit_value_t value) { jit_insn_t insn; - jit_insn_t addrof; jit_value_t offset_value; +#if ACCUMULATE_RELATIVE + jit_value_t addrof; + jit_value_t new_dest; + jit_nint new_offset; +#else + jit_insn_t addrof; +#endif if(!dest || !value) { return 0; @@ -1628,6 +1727,13 @@ int jit_insn_store_relative { return 0; } +#if ACCUMULATE_RELATIVE + if(accumulate_relative_offset(func, dest, offset, &addrof, &new_dest, &new_offset)) + { + dest = new_dest; + offset = new_offset; + } +#else insn = previous_relative(func, dest, &addrof); if(insn) { @@ -1656,6 +1762,7 @@ int jit_insn_store_relative addrof->value2 = 0; } } +#endif offset_value = jit_value_create_nint_constant(func, jit_type_nint, offset); if(!offset_value) { @@ -1690,6 +1797,26 @@ int jit_insn_store_relative jit_value_t jit_insn_add_relative (jit_function_t func, jit_value_t value, jit_nint offset) { +#if ACCUMULATE_RELATIVE + jit_value_t new_value; + jit_nint new_offset; + if(!value) + { + return 0; + } + if(!_jit_function_ensure_builder(func)) + { + return 0; + } + if(accumulate_relative_offset(func, value, offset, 0, &new_value, &new_offset)) + { + value = new_value; + offset = new_offset; + } + return apply_binary(func, JIT_OP_ADD_RELATIVE, value, + jit_value_create_nint_constant(func, jit_type_nint, offset), + jit_type_void_ptr); +#else jit_insn_t insn; jit_insn_t addrof; if(!value) @@ -1717,6 +1844,7 @@ jit_value_t jit_insn_add_relative (func, jit_type_nint, offset), jit_type_void_ptr); } +#endif } /*@ @@ -7874,10 +8002,13 @@ int jit_insn_move_blocks_to_start @*/ int jit_insn_mark_offset(jit_function_t func, jit_int offset) { +#if 1 + /*|| !USE_NEW_REG_ALLOC*/ if(!jit_insn_new_block(func)) { return 0; } +#endif return create_unary_note(func, JIT_OP_MARK_OFFSET, jit_value_create_nint_constant (func, jit_type_int, offset));