Make more use of subreg_lowpart_offset
authorRichard Sandiford <richard.sandiford@linaro.org>
Fri, 13 Oct 2017 09:23:54 +0000 (09:23 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 13 Oct 2017 09:23:54 +0000 (09:23 +0000)
This patch uses subreg_lowpart_offset in places that open-coded
the calculation.  It also uses it in regcprop.c to test whether,
after a mode change, the first register in a multi-register group
is still the right one.

2017-10-13  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* calls.c (expand_call): Use subreg_lowpart_offset.
* cse.c (cse_insn): Likewise.
* regcprop.c (copy_value): Likewise.
(copyprop_hardreg_forward_1): Likewise.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r253713

gcc/ChangeLog
gcc/calls.c
gcc/cse.c
gcc/regcprop.c

index cb9f1a3..dc2d911 100644 (file)
@@ -1,3 +1,12 @@
+2017-10-13  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * calls.c (expand_call): Use subreg_lowpart_offset.
+       * cse.c (cse_insn): Likewise.
+       * regcprop.c (copy_value): Likewise.
+       (copyprop_hardreg_forward_1): Likewise.
+
 2017-10-13  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/82524
index 4d54fc6..7ed05d4 100644 (file)
@@ -4117,7 +4117,6 @@ expand_call (tree exp, rtx target, int ignore)
        {
          tree type = rettype;
          int unsignedp = TYPE_UNSIGNED (type);
-         int offset = 0;
          machine_mode pmode;
 
          /* Ensure we promote as expected, and get the new unsignedness.  */
@@ -4125,18 +4124,8 @@ expand_call (tree exp, rtx target, int ignore)
                                         funtype, 1);
          gcc_assert (GET_MODE (target) == pmode);
 
-         if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
-             && (GET_MODE_SIZE (GET_MODE (target))
-                 > GET_MODE_SIZE (TYPE_MODE (type))))
-           {
-             offset = GET_MODE_SIZE (GET_MODE (target))
-               - GET_MODE_SIZE (TYPE_MODE (type));
-             if (! BYTES_BIG_ENDIAN)
-               offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
-             else if (! WORDS_BIG_ENDIAN)
-               offset %= UNITS_PER_WORD;
-           }
-
+         unsigned int offset = subreg_lowpart_offset (TYPE_MODE (type),
+                                                      GET_MODE (target));
          target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
          SUBREG_PROMOTED_VAR_P (target) = 1;
          SUBREG_PROMOTED_SET (target, unsignedp);
index 672fd2e..717aaf8 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -5977,7 +5977,6 @@ cse_insn (rtx_insn *insn)
                rtx new_src = 0;
                unsigned src_hash;
                struct table_elt *src_elt;
-               int byte = 0;
 
                /* Ignore invalid entries.  */
                if (!REG_P (elt->exp)
@@ -5990,13 +5989,8 @@ cse_insn (rtx_insn *insn)
                  new_src = elt->exp;
                else
                  {
-                   /* Calculate big endian correction for the SUBREG_BYTE.
-                      We have already checked that M1 (GET_MODE (dest))
-                      is not narrower than M2 (new_mode).  */
-                   if (BYTES_BIG_ENDIAN)
-                     byte = (GET_MODE_SIZE (GET_MODE (dest))
-                             - GET_MODE_SIZE (new_mode));
-
+                   unsigned int byte
+                     = subreg_lowpart_offset (new_mode, GET_MODE (dest));
                    new_src = simplify_gen_subreg (new_mode, elt->exp,
                                                   GET_MODE (dest), byte);
                  }
index 73e945d..5db5b5d 100644 (file)
@@ -345,8 +345,7 @@ copy_value (rtx dest, rtx src, struct value_data *vd)
      We can't properly represent the latter case in our tables, so don't
      record anything then.  */
   else if (sn < hard_regno_nregs (sr, vd->e[sr].mode)
-          && (GET_MODE_SIZE (vd->e[sr].mode) > UNITS_PER_WORD
-              ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
+          && subreg_lowpart_offset (GET_MODE (dest), vd->e[sr].mode) != 0)
     return;
 
   /* If SRC had been assigned a mode narrower than the copy, we can't
@@ -871,8 +870,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
              /* And likewise, if we are narrowing on big endian the transformation
                 is also invalid.  */
              if (REG_NREGS (src) < hard_regno_nregs (regno, vd->e[regno].mode)
-                 && (GET_MODE_SIZE (vd->e[regno].mode) > UNITS_PER_WORD
-                     ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
+                 && subreg_lowpart_offset (mode, vd->e[regno].mode) != 0)
                goto no_move_special_case;
            }