From: Simon Dardis Date: Thu, 20 Aug 2015 09:45:33 +0000 (+0100) Subject: mips.c (mips_expand_block_move): Enable inline memcpy expansion when !ISA_HAS_LWL_LWR. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=58df0b91cbca6814b243256bb7900341b5316d14;p=gcc.git mips.c (mips_expand_block_move): Enable inline memcpy expansion when !ISA_HAS_LWL_LWR. 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 78a7a7930ba..62459e78af6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-08-20 Simon Dardis + + * 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 * expr.c (expand_expr_real_2): Check gimple statement during diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 401d73bfeaa..0b4a5faacdb 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -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)) diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index da1de011fc9..2d44735e6ca 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -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 \ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 076de9ca606..be331444423 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-08-20 Simon Dardis + + * 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 * 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 index 00000000000..5a254b1eaa9 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/inline-memcpy-1.c @@ -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 + +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 index 00000000000..e144e61a800 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/inline-memcpy-2.c @@ -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 + +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 index 00000000000..96a0387fce5 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/inline-memcpy-3.c @@ -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 + +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 index 00000000000..0e7a22e8a33 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/inline-memcpy-4.c @@ -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 + +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 index 00000000000..1b9fa16b2a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/inline-memcpy-5.c @@ -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 + +char c[40] __attribute__ ((aligned(2))); + +void +f1 () +{ + memcpy (c, "1234567890QWERTYUIOPASDFGHJKLZXCVBNM", 32); +}