From 1e047eedb4c116f861f9d781b0a36821084242ef Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 30 Aug 2017 11:12:41 +0000 Subject: [PATCH] [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 Alan Hayward David Sherwood * 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 --- gcc/postreload.c | 56 ++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/gcc/postreload.c b/gcc/postreload.c index 38948dcf9c5..39eebf7877b 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -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 (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; } -- 2.30.2