Commit 1e047eed by Richard Sandiford

[31/77] Use scalar_int_mode for move2add

The postreload move2add optimisations are specific to scalar
integers.  This patch adds an explicit check to the main guarding
"if" and propagates the information through subroutines.

gcc/
2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

	* postreload.c (move2add_valid_value_p): Change the type of the
	mode parameter to scalar_int_mode.
	(move2add_use_add2_insn): Add a mode parameter and use it instead
	of GET_MODE (reg).
	(move2add_use_add3_insn): Likewise.
	(reload_cse_move2add): Update accordingly.

From-SVN: r251483
parent e4dc9904
......@@ -1692,7 +1692,7 @@ move2add_record_sym_value (rtx reg, rtx sym, rtx off)
/* Check if REGNO contains a valid value in MODE. */
static bool
move2add_valid_value_p (int regno, machine_mode mode)
move2add_valid_value_p (int regno, scalar_int_mode mode)
{
if (reg_set_luid[regno] <= move2add_last_label_luid)
return false;
......@@ -1723,21 +1723,21 @@ move2add_valid_value_p (int regno, machine_mode mode)
return true;
}
/* This function is called with INSN that sets REG to (SYM + OFF),
while REG is known to already have value (SYM + offset).
/* This function is called with INSN that sets REG (of mode MODE)
to (SYM + OFF), while REG is known to already have value (SYM + offset).
This function tries to change INSN into an add instruction
(set (REG) (plus (REG) (OFF - offset))) using the known value.
It also updates the information about REG's known value.
Return true if we made a change. */
static bool
move2add_use_add2_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn)
move2add_use_add2_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
rtx_insn *insn)
{
rtx pat = PATTERN (insn);
rtx src = SET_SRC (pat);
int regno = REGNO (reg);
rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno],
GET_MODE (reg));
rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno], mode);
bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
bool changed = false;
......@@ -1759,7 +1759,7 @@ move2add_use_add2_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn)
else
{
struct full_rtx_costs oldcst, newcst;
rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
rtx tem = gen_rtx_PLUS (mode, reg, new_src);
get_full_set_rtx_cost (pat, &oldcst);
SET_SRC (pat) = tem;
......@@ -1769,10 +1769,10 @@ move2add_use_add2_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn)
if (costs_lt_p (&newcst, &oldcst, speed)
&& have_add2_insn (reg, new_src))
changed = validate_change (insn, &SET_SRC (pat), tem, 0);
else if (sym == NULL_RTX && GET_MODE (reg) != BImode)
else if (sym == NULL_RTX && mode != BImode)
{
machine_mode narrow_mode;
FOR_EACH_MODE_UNTIL (narrow_mode, GET_MODE (reg))
scalar_int_mode narrow_mode;
FOR_EACH_MODE_UNTIL (narrow_mode, mode)
{
if (have_insn_for (STRICT_LOW_PART, narrow_mode)
&& ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode))
......@@ -1802,9 +1802,9 @@ move2add_use_add2_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn)
}
/* This function is called with INSN that sets REG to (SYM + OFF),
but REG doesn't have known value (SYM + offset). This function
tries to find another register which is known to already have
/* This function is called with INSN that sets REG (of mode MODE) to
(SYM + OFF), but REG doesn't have known value (SYM + offset). This
function tries to find another register which is known to already have
value (SYM + offset) and change INSN into an add instruction
(set (REG) (plus (the found register) (OFF - offset))) if such
a register is found. It also updates the information about
......@@ -1812,7 +1812,8 @@ move2add_use_add2_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn)
Return true iff we made a change. */
static bool
move2add_use_add3_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn)
move2add_use_add3_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
rtx_insn *insn)
{
rtx pat = PATTERN (insn);
rtx src = SET_SRC (pat);
......@@ -1831,7 +1832,7 @@ move2add_use_add3_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn)
SET_SRC (pat) = plus_expr;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (move2add_valid_value_p (i, GET_MODE (reg))
if (move2add_valid_value_p (i, mode)
&& reg_base_reg[i] < 0
&& reg_symbol_ref[i] != NULL_RTX
&& rtx_equal_p (sym, reg_symbol_ref[i]))
......@@ -1921,8 +1922,10 @@ reload_cse_move2add (rtx_insn *first)
pat = PATTERN (insn);
/* For simplicity, we only perform this optimization on
straightforward SETs. */
scalar_int_mode mode;
if (GET_CODE (pat) == SET
&& REG_P (SET_DEST (pat)))
&& REG_P (SET_DEST (pat))
&& is_a <scalar_int_mode> (GET_MODE (SET_DEST (pat)), &mode))
{
rtx reg = SET_DEST (pat);
int regno = REGNO (reg);
......@@ -1930,7 +1933,7 @@ reload_cse_move2add (rtx_insn *first)
/* Check if we have valid information on the contents of this
register in the mode of REG. */
if (move2add_valid_value_p (regno, GET_MODE (reg))
if (move2add_valid_value_p (regno, mode)
&& dbg_cnt (cse2_move2add))
{
/* Try to transform (set (REGX) (CONST_INT A))
......@@ -1950,7 +1953,8 @@ reload_cse_move2add (rtx_insn *first)
&& reg_base_reg[regno] < 0
&& reg_symbol_ref[regno] == NULL_RTX)
{
changed |= move2add_use_add2_insn (reg, NULL_RTX, src, insn);
changed |= move2add_use_add2_insn (mode, reg, NULL_RTX,
src, insn);
continue;
}
......@@ -1967,7 +1971,7 @@ reload_cse_move2add (rtx_insn *first)
else if (REG_P (src)
&& reg_set_luid[regno] == reg_set_luid[REGNO (src)]
&& reg_base_reg[regno] == reg_base_reg[REGNO (src)]
&& move2add_valid_value_p (REGNO (src), GET_MODE (reg)))
&& move2add_valid_value_p (REGNO (src), mode))
{
rtx_insn *next = next_nonnote_nondebug_insn (insn);
rtx set = NULL_RTX;
......@@ -1987,7 +1991,7 @@ reload_cse_move2add (rtx_insn *first)
gen_int_mode (added_offset
+ base_offset
- regno_offset,
GET_MODE (reg));
mode);
bool success = false;
bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
......@@ -1999,11 +2003,11 @@ reload_cse_move2add (rtx_insn *first)
{
rtx old_src = SET_SRC (set);
struct full_rtx_costs oldcst, newcst;
rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
rtx tem = gen_rtx_PLUS (mode, reg, new_src);
get_full_set_rtx_cost (set, &oldcst);
SET_SRC (set) = tem;
get_full_set_src_cost (tem, GET_MODE (reg), &newcst);
get_full_set_src_cost (tem, mode, &newcst);
SET_SRC (set) = old_src;
costs_add_n_insns (&oldcst, 1);
......@@ -2023,7 +2027,7 @@ reload_cse_move2add (rtx_insn *first)
move2add_record_mode (reg);
reg_offset[regno]
= trunc_int_for_mode (added_offset + base_offset,
GET_MODE (reg));
mode);
continue;
}
}
......@@ -2059,16 +2063,16 @@ reload_cse_move2add (rtx_insn *first)
/* If the reg already contains the value which is sum of
sym and some constant value, we can use an add2 insn. */
if (move2add_valid_value_p (regno, GET_MODE (reg))
if (move2add_valid_value_p (regno, mode)
&& reg_base_reg[regno] < 0
&& reg_symbol_ref[regno] != NULL_RTX
&& rtx_equal_p (sym, reg_symbol_ref[regno]))
changed |= move2add_use_add2_insn (reg, sym, off, insn);
changed |= move2add_use_add2_insn (mode, reg, sym, off, insn);
/* Otherwise, we have to find a register whose value is sum
of sym and some constant value. */
else
changed |= move2add_use_add3_insn (reg, sym, off, insn);
changed |= move2add_use_add3_insn (mode, reg, sym, off, insn);
continue;
}
......
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