mips.c (mips_expand_block_move): Enable inline memcpy expansion when !ISA_HAS_LWL_LWR.
authorSimon Dardis <simon.dardis@imgtec.com>
Thu, 20 Aug 2015 09:45:33 +0000 (10:45 +0100)
committerSimon Dardis <dardiss@gcc.gnu.org>
Thu, 20 Aug 2015 09:45:33 +0000 (10:45 +0100)
gcc/

   * config/mips/mips.c (mips_expand_block_move): Enable inline memcpy
expansion when !ISA_HAS_LWL_LWR.
(mips_block_move_straight): Update the size of elements copied to
account for alignment when !ISA_HAS_LWL_LWR.
* config/mips/mips.h (MIPS_MIN_MOVE_MEM_ALIGN): New macro.

gcc/testsuite/

* inline-memcpy-1.c: Test for inline expansion of memcpy.
* inline-memcpy-2.c: Ditto.
* inline-memcpy-3.c: Ditto.
* inline-memcpy-4.c: Ditto.
* inline-memcpy-5.c: Ditto.

From-SVN: r227026

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/inline-memcpy-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/inline-memcpy-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/inline-memcpy-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/inline-memcpy-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/inline-memcpy-5.c [new file with mode: 0644]

index 78a7a7930ba493bfbbe462998a59bd3c3df2e248..62459e78af6fca4a5e910d3aa192817787f58bdc 100644 (file)
@@ -1,3 +1,11 @@
+2015-08-20  Simon Dardis  <simon.dardis@imgtec.com>
+
+       * config/mips/mips.c (mips_expand_block_move): Enable inline memcpy
+       expansion when !ISA_HAS_LWL_LWR.
+       (mips_block_move_straight): Update the size of elements copied to
+       account for alignment when !ISA_HAS_LWL_LWR.
+       * config/mips/mips.h (MIPS_MIN_MOVE_MEM_ALIGN): New macro.
+
 2015-08-19  Jiong Wang  <jiong.wang@arm.com>
 
        * expr.c (expand_expr_real_2): Check gimple statement during
index 401d73bfeaa72e10eac6d9a211c58c0c1bef6868..0b4a5faacdb93ed5b6ad436ef79f44185b816eb6 100644 (file)
@@ -7630,12 +7630,22 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
      half-word alignment, it is usually better to move in half words.
      For instance, lh/lh/sh/sh is usually better than lwl/lwr/swl/swr
      and lw/lw/sw/sw is usually better than ldl/ldr/sdl/sdr.
-     Otherwise move word-sized chunks.  */
-  if (MEM_ALIGN (src) == BITS_PER_WORD / 2
-      && MEM_ALIGN (dest) == BITS_PER_WORD / 2)
-    bits = BITS_PER_WORD / 2;
+     Otherwise move word-sized chunks.
+
+     For ISA_HAS_LWL_LWR we rely on the lwl/lwr & swl/swr load. Otherwise
+     picking the minimum of alignment or BITS_PER_WORD gets us the
+     desired size for bits.  */
+
+  if (!ISA_HAS_LWL_LWR)
+    bits = MIN (BITS_PER_WORD, MIN (MEM_ALIGN (src), MEM_ALIGN (dest)));
   else
-    bits = BITS_PER_WORD;
+    {
+      if (MEM_ALIGN (src) == BITS_PER_WORD / 2
+         && MEM_ALIGN (dest) == BITS_PER_WORD / 2)
+       bits = BITS_PER_WORD / 2;
+      else
+       bits = BITS_PER_WORD;
+    }
 
   mode = mode_for_size (bits, MODE_INT, 0);
   delta = bits / BITS_PER_UNIT;
@@ -7754,8 +7764,9 @@ mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
 bool
 mips_expand_block_move (rtx dest, rtx src, rtx length)
 {
-  /* Disable entirely for R6 initially.  */
-  if (!ISA_HAS_LWL_LWR)
+  if (!ISA_HAS_LWL_LWR
+      && (MEM_ALIGN (src) < MIPS_MIN_MOVE_MEM_ALIGN
+         || MEM_ALIGN (dest) < MIPS_MIN_MOVE_MEM_ALIGN))
     return false;
 
   if (CONST_INT_P (length))
index da1de011fc99f1aa8c4a914174726d248a2745d8..2d44735e6ca35fc9a97ffff82612f1c5ae92441d 100644 (file)
@@ -2981,6 +2981,9 @@ while (0)
 #undef PTRDIFF_TYPE
 #define PTRDIFF_TYPE (POINTER_SIZE == 64 ? "long int" : "int")
 
+/* The minimum alignment of any expanded block move.  */
+#define MIPS_MIN_MOVE_MEM_ALIGN 16
+
 /* The maximum number of bytes that can be copied by one iteration of
    a movmemsi loop; see mips_block_move_loop.  */
 #define MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER \
index 076de9ca6063787020ff536b847155d55b45f61e..be3314444230dffe93d9fc7700761afc9c025b38 100644 (file)
@@ -1,3 +1,11 @@
+2015-08-20  Simon Dardis  <simon.dardis@imgtec.com>
+
+       * gcc.target/mips/inline-memcpy-1.c: Test for inline expansion of memcpy.
+       * gcc.target/mips/inline-memcpy-2.c: Ditto.
+       * gcc.target/mips/inline-memcpy-3.c: Ditto.
+       * gcc.target/mips/inline-memcpy-4.c: Ditto.
+       * gcc.target/mips/inline-memcpy-5.c: Ditto.
+
 2015-08-19  Jiong Wang  <jiong.wang@arm.com>
 
        * gcc.dg/wide_shift_64_1.c: New testcase.
diff --git a/gcc/testsuite/gcc.target/mips/inline-memcpy-1.c b/gcc/testsuite/gcc.target/mips/inline-memcpy-1.c
new file mode 100644 (file)
index 0000000..5a254b1
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-options "-fno-common isa_rev>=6" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os" } { "" } } */
+/* { dg-final { scan-assembler-not "\tmemcpy" } } */
+
+/* Test that memcpy is inline for target hardware
+   without swl, swr.  */
+
+#include <string.h>
+
+char c[40] __attribute__ ((aligned(8)));
+
+void
+f1 ()
+{
+  memcpy (c, "1234567890QWERTYUIOPASDFGHJKLZXCVBNM", 32);
+}
diff --git a/gcc/testsuite/gcc.target/mips/inline-memcpy-2.c b/gcc/testsuite/gcc.target/mips/inline-memcpy-2.c
new file mode 100644 (file)
index 0000000..e144e61
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-options "-fno-common isa_rev>=6" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os"} { "" } } */
+/* { dg-final { scan-assembler-not "\tmemcpy" } } */
+/* { dg-final { scan-assembler-times "\tsh\t" 16 } } */
+
+/* Test that inline memcpy is expanded for target hardware without
+   swl, swr when alignment is halfword and sufficent shs are produced.  */
+
+#include <string.h>
+
+char c[40] __attribute__ ((aligned(2)));
+
+void
+f1 ()
+{
+  memcpy (c, "1234567890QWERTYUIOPASDFGHJKLZXCVBNM", 32);
+}
diff --git a/gcc/testsuite/gcc.target/mips/inline-memcpy-3.c b/gcc/testsuite/gcc.target/mips/inline-memcpy-3.c
new file mode 100644 (file)
index 0000000..96a0387
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-options "-fno-common isa_rev<=5" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os"} { "" } } */
+/* { dg-final { scan-assembler-not "\tmemcpy" } } */
+/* { dg-final { scan-assembler-times "swl" 8 } } */
+/* { dg-final { scan-assembler-times "swr" 8 } } */
+
+/* Test that inline memcpy for hardware with swl, swr handles subword
+   alignment and produces enough swl/swrs for mips32.  */
+
+#include <string.h>
+
+char c[40] __attribute__ ((aligned(2)));
+
+void
+f1 ()
+{
+  memcpy (c, "1234567890QWERTYUIOPASDFGHJKLZXCVBNM", 32);
+}
diff --git a/gcc/testsuite/gcc.target/mips/inline-memcpy-4.c b/gcc/testsuite/gcc.target/mips/inline-memcpy-4.c
new file mode 100644 (file)
index 0000000..0e7a22e
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-options "-fno-common isa_rev<=5 -mabi=64" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os"} { "" } } */
+/* { dg-final { scan-assembler-not "\tmemcpy" } } */
+/* { dg-final { scan-assembler-times "sdl" 4 } } */
+/* { dg-final { scan-assembler-times "sdr" 4 } } */
+
+/* Test that inline memcpy for hardware with sdl, sdr handles subword
+   alignment and produces enough sdl/sdrs on n64.  */
+
+#include <string.h>
+
+char c[40] __attribute__ ((aligned(2)));
+
+void
+f1 ()
+{
+  memcpy (c, "1234567890QWERTYUIOPASDFGHJKLZXCVBNM", 32);
+}
diff --git a/gcc/testsuite/gcc.target/mips/inline-memcpy-5.c b/gcc/testsuite/gcc.target/mips/inline-memcpy-5.c
new file mode 100644 (file)
index 0000000..1b9fa16
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-options "-fno-common isa_rev<=5 -mabi=n32" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os"} { "" } } */
+/* { dg-final { scan-assembler-not "\tmemcpy" } } */
+/* { dg-final { scan-assembler-times "sdl" 4 } } */
+/* { dg-final { scan-assembler-times "sdr" 4 } } */
+
+/* Test that inline memcpy for hardware with sdl, sdr handles subword
+   alignment and produces enough sdr/sdls on n32.  */
+
+#include <string.h>
+
+char c[40] __attribute__ ((aligned(2)));
+
+void
+f1 ()
+{
+  memcpy (c, "1234567890QWERTYUIOPASDFGHJKLZXCVBNM", 32);
+}