diff options
author | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-27 15:20:14 +0000 |
---|---|---|
committer | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-27 15:20:14 +0000 |
commit | 692ec7c8f19ad412b2d90c1fcf58429d3a413b94 (patch) | |
tree | 84746048bc8fb1990194b86d153cea947400830d /gcc/postreload.c | |
parent | fecf90116e4c155515833b5e939cdaad4afb9b53 (diff) | |
download | linaro-gcc-692ec7c8f19ad412b2d90c1fcf58429d3a413b94.tar.gz linaro-gcc-692ec7c8f19ad412b2d90c1fcf58429d3a413b94.tar.bz2 linaro-gcc-692ec7c8f19ad412b2d90c1fcf58429d3a413b94.zip |
* postreload.c (try_replace_in_use): New static function.
(reload_combine_recognize_const_pattern): Use it here. Allow
substituting into a final add insn, and substituting into a memory
reference in an insn that sets the reg.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162573 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/postreload.c')
-rw-r--r-- | gcc/postreload.c | 150 |
1 files changed, 80 insertions, 70 deletions
diff --git a/gcc/postreload.c b/gcc/postreload.c index 2c6a8c590d0..093dce717b0 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -871,6 +871,61 @@ fixup_debug_insns (rtx reg, rtx replacement, rtx from, rtx to) } } +/* Subroutine of reload_combine_recognize_const_pattern. Try to replace REG + with SRC in the insn described by USE, taking costs into account. Return + true if we made the replacement. */ + +static bool +try_replace_in_use (struct reg_use *use, rtx reg, rtx src) +{ + rtx use_insn = use->insn; + rtx mem = use->containing_mem; + bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn)); + + if (mem != NULL_RTX) + { + addr_space_t as = MEM_ADDR_SPACE (mem); + rtx oldaddr = XEXP (mem, 0); + rtx newaddr = NULL_RTX; + int old_cost = address_cost (oldaddr, GET_MODE (mem), as, speed); + int new_cost; + + newaddr = simplify_replace_rtx (oldaddr, reg, src); + if (memory_address_addr_space_p (GET_MODE (mem), newaddr, as)) + { + XEXP (mem, 0) = newaddr; + new_cost = address_cost (newaddr, GET_MODE (mem), as, speed); + XEXP (mem, 0) = oldaddr; + if (new_cost <= old_cost + && validate_change (use_insn, + &XEXP (mem, 0), newaddr, 0)) + return true; + } + } + else + { + rtx new_set = single_set (use_insn); + if (new_set + && REG_P (SET_DEST (new_set)) + && GET_CODE (SET_SRC (new_set)) == PLUS + && REG_P (XEXP (SET_SRC (new_set), 0)) + && CONSTANT_P (XEXP (SET_SRC (new_set), 1))) + { + rtx new_src; + int old_cost = rtx_cost (SET_SRC (new_set), SET, speed); + + gcc_assert (rtx_equal_p (XEXP (SET_SRC (new_set), 0), reg)); + new_src = simplify_replace_rtx (SET_SRC (new_set), reg, src); + + if (rtx_cost (new_src, SET, speed) <= old_cost + && validate_change (use_insn, &SET_SRC (new_set), + new_src, 0)) + return true; + } + } + return false; +} + /* Called by reload_combine when scanning INSN. This function tries to detect patterns where a constant is added to a register, and the result is used in an address. @@ -940,10 +995,9 @@ reload_combine_recognize_const_pattern (rtx insn) if (use && GET_MODE (*use->usep) == Pmode) { + bool delete_add = false; rtx use_insn = use->insn; int use_ruid = use->ruid; - rtx mem = use->containing_mem; - bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn)); /* Avoid moving the add insn past a jump. */ if (must_move_add && use_ruid <= last_jump_ruid) @@ -957,81 +1011,37 @@ reload_combine_recognize_const_pattern (rtx insn) gcc_assert (reg_state[regno].store_ruid <= use_ruid); /* Avoid moving a use of ADDREG past a point where it is stored. */ - if (reg_state[REGNO (addreg)].store_ruid >= use_ruid) + if (reg_state[REGNO (addreg)].store_ruid > use_ruid) break; - if (mem != NULL_RTX) + /* We also must not move the addition past an insn that sets + the same register, unless we can combine two add insns. */ + if (must_move_add && reg_state[regno].store_ruid == use_ruid) { - addr_space_t as = MEM_ADDR_SPACE (mem); - rtx oldaddr = XEXP (mem, 0); - rtx newaddr = NULL_RTX; - int old_cost = address_cost (oldaddr, GET_MODE (mem), as, speed); - int new_cost; - - newaddr = simplify_replace_rtx (oldaddr, reg, src); - if (memory_address_addr_space_p (GET_MODE (mem), newaddr, as)) - { - XEXP (mem, 0) = newaddr; - new_cost = address_cost (newaddr, GET_MODE (mem), as, speed); - XEXP (mem, 0) = oldaddr; - if (new_cost <= old_cost - && validate_change (use_insn, - &XEXP (mem, 0), newaddr, 0)) - { - reload_combine_purge_insn_uses (use_insn); - reload_combine_note_use (&PATTERN (use_insn), use_insn, - use_ruid, NULL_RTX); - - if (must_move_add) - { - add_moved_after_insn = use_insn; - add_moved_after_ruid = use_ruid; - } - continue; - } - } + if (use->containing_mem == NULL_RTX) + delete_add = true; + else + break; } - else - { - rtx new_set = single_set (use_insn); - if (new_set - && REG_P (SET_DEST (new_set)) - && GET_CODE (SET_SRC (new_set)) == PLUS - && REG_P (XEXP (SET_SRC (new_set), 0)) - && CONSTANT_P (XEXP (SET_SRC (new_set), 1))) - { - rtx new_src; - int old_cost = rtx_cost (SET_SRC (new_set), SET, speed); - - gcc_assert (rtx_equal_p (XEXP (SET_SRC (new_set), 0), reg)); - new_src = simplify_replace_rtx (SET_SRC (new_set), reg, src); - if (rtx_cost (new_src, SET, speed) <= old_cost - && validate_change (use_insn, &SET_SRC (new_set), - new_src, 0)) - { - reload_combine_purge_insn_uses (use_insn); - reload_combine_note_use (&SET_SRC (new_set), use_insn, - use_ruid, NULL_RTX); + if (try_replace_in_use (use, reg, src)) + { + reload_combine_purge_insn_uses (use_insn); + reload_combine_note_use (&PATTERN (use_insn), use_insn, + use_ruid, NULL_RTX); - if (must_move_add) - { - /* See if that took care of the add insn. */ - if (rtx_equal_p (SET_DEST (new_set), reg)) - { - fixup_debug_insns (reg, src, insn, use_insn); - delete_insn (insn); - return true; - } - else - { - add_moved_after_insn = use_insn; - add_moved_after_ruid = use_ruid; - } - } - continue; - } + if (delete_add) + { + fixup_debug_insns (reg, src, insn, use_insn); + delete_insn (insn); + return true; } + if (must_move_add) + { + add_moved_after_insn = use_insn; + add_moved_after_ruid = use_ruid; + } + continue; } } /* If we get here, we couldn't handle this use. */ |