Commit a78e242c by Bernd Schmidt Committed by Bernd Schmidt

postreload.c (try_replace_in_use): New static function.

	* 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.

From-SVN: r162573
parent 61ff2bdc
2010-07-27 Bernd Schmidt <bernds@codesourcery.com>
* 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.
2010-07-27 Joseph Myers <joseph@codesourcery.com> 2010-07-27 Joseph Myers <joseph@codesourcery.com>
* common.opt (o): Add MissingArgError. * common.opt (o): Add MissingArgError.
......
...@@ -871,6 +871,61 @@ fixup_debug_insns (rtx reg, rtx replacement, rtx from, rtx to) ...@@ -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 /* 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 patterns where a constant is added to a register, and the result is used
in an address. in an address.
...@@ -940,10 +995,9 @@ reload_combine_recognize_const_pattern (rtx insn) ...@@ -940,10 +995,9 @@ reload_combine_recognize_const_pattern (rtx insn)
if (use && GET_MODE (*use->usep) == Pmode) if (use && GET_MODE (*use->usep) == Pmode)
{ {
bool delete_add = false;
rtx use_insn = use->insn; rtx use_insn = use->insn;
int use_ruid = use->ruid; 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. */ /* Avoid moving the add insn past a jump. */
if (must_move_add && use_ruid <= last_jump_ruid) if (must_move_add && use_ruid <= last_jump_ruid)
...@@ -957,81 +1011,37 @@ reload_combine_recognize_const_pattern (rtx insn) ...@@ -957,81 +1011,37 @@ reload_combine_recognize_const_pattern (rtx insn)
gcc_assert (reg_state[regno].store_ruid <= use_ruid); gcc_assert (reg_state[regno].store_ruid <= use_ruid);
/* Avoid moving a use of ADDREG past a point where it is stored. */ /* 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; 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); if (use->containing_mem == NULL_RTX)
rtx oldaddr = XEXP (mem, 0); delete_add = true;
rtx newaddr = NULL_RTX; else
int old_cost = address_cost (oldaddr, GET_MODE (mem), as, speed); break;
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;
}
}
} }
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 if (try_replace_in_use (use, reg, src))
&& validate_change (use_insn, &SET_SRC (new_set), {
new_src, 0)) reload_combine_purge_insn_uses (use_insn);
{ reload_combine_note_use (&PATTERN (use_insn), use_insn,
reload_combine_purge_insn_uses (use_insn); use_ruid, NULL_RTX);
reload_combine_note_use (&SET_SRC (new_set), use_insn,
use_ruid, NULL_RTX);
if (must_move_add) if (delete_add)
{ {
/* See if that took care of the add insn. */ fixup_debug_insns (reg, src, insn, use_insn);
if (rtx_equal_p (SET_DEST (new_set), reg)) delete_insn (insn);
{ return true;
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 (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. */ /* If we get here, we couldn't handle this use. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment