[31/77] Use scalar_int_mode for move2add
authorRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 30 Aug 2017 11:12:41 +0000 (11:12 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 30 Aug 2017 11:12:41 +0000 (11:12 +0000)
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

gcc/postreload.c

index 38948dcf9c5b4a35a09df1a8fd8d9e790929d5fd..39eebf7877baad93890daac4c178dc689df1a52b 100644 (file)
@@ -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;
            }