diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-04-22 12:46:07 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-04-22 12:46:07 +0000 |
commit | ac875fa40bf5429aff0612943d8c5705c4e11bb5 (patch) | |
tree | 6254ef8bed13933fcdfb55163f89625f1932c652 | |
parent | 3efb5d22322a504342153f3d64f1a3a209c3fe40 (diff) | |
download | gcc-ac875fa40bf5429aff0612943d8c5705c4e11bb5.tar.gz |
gcc/
* machmode.h (bitwise_mode_for_mode): Declare.
* stor-layout.h (bitwise_type_for_mode): Likewise.
* stor-layout.c (bitwise_mode_for_mode): New function.
(bitwise_type_for_mode): Likewise.
* builtins.c (fold_builtin_memory_op): Use it instead of
int_mode_for_mode and build_nonstandard_integer_type.
gcc/testsuite/
* gcc.dg/memcpy-5.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@209622 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/builtins.c | 22 | ||||
-rw-r--r-- | gcc/machmode.h | 2 | ||||
-rw-r--r-- | gcc/stor-layout.c | 67 | ||||
-rw-r--r-- | gcc/stor-layout.h | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/memcpy-5.c | 27 |
7 files changed, 113 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a0220156d8e..3a46e6f66b8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2014-04-22 Richard Sandiford <rdsandiford@googlemail.com> + + * machmode.h (bitwise_mode_for_mode): Declare. + * stor-layout.h (bitwise_type_for_mode): Likewise. + * stor-layout.c (bitwise_mode_for_mode): New function. + (bitwise_type_for_mode): Likewise. + * builtins.c (fold_builtin_memory_op): Use it instead of + int_mode_for_mode and build_nonstandard_integer_type. + 2014-04-22 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> * config.gcc (enable_obsolete): Remove *-*-solaris2.9*. diff --git a/gcc/builtins.c b/gcc/builtins.c index dd57b1ae42a..42e4af263ab 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -8921,29 +8921,11 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, if (FLOAT_MODE_P (TYPE_MODE (desttype)) || TREE_CODE (desttype) == BOOLEAN_TYPE || TREE_CODE (desttype) == ENUMERAL_TYPE) - { - /* A more suitable int_mode_for_mode would return a vector - integer mode for a vector float mode or a integer complex - mode for a float complex mode if there isn't a regular - integer mode covering the mode of desttype. */ - enum machine_mode mode = int_mode_for_mode (TYPE_MODE (desttype)); - if (mode == BLKmode) - desttype = NULL_TREE; - else - desttype = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), - 1); - } + desttype = bitwise_type_for_mode (TYPE_MODE (desttype)); if (FLOAT_MODE_P (TYPE_MODE (srctype)) || TREE_CODE (srctype) == BOOLEAN_TYPE || TREE_CODE (srctype) == ENUMERAL_TYPE) - { - enum machine_mode mode = int_mode_for_mode (TYPE_MODE (srctype)); - if (mode == BLKmode) - srctype = NULL_TREE; - else - srctype = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), - 1); - } + srctype = bitwise_type_for_mode (TYPE_MODE (srctype)); if (!srctype) srctype = desttype; if (!desttype) diff --git a/gcc/machmode.h b/gcc/machmode.h index 222e6263e0b..8d6ea187b4d 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -271,6 +271,8 @@ extern enum machine_mode smallest_mode_for_size (unsigned int, extern enum machine_mode int_mode_for_mode (enum machine_mode); +extern enum machine_mode bitwise_mode_for_mode (enum machine_mode); + /* Return a mode that is suitable for representing a vector, or BLKmode on failure. */ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index e3f8406626b..4f99fa3469a 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -403,6 +403,73 @@ int_mode_for_mode (enum machine_mode mode) return mode; } +/* Find a mode that can be used for efficient bitwise operations on MODE. + Return BLKmode if no such mode exists. */ + +enum machine_mode +bitwise_mode_for_mode (enum machine_mode mode) +{ + /* Quick exit if we already have a suitable mode. */ + unsigned int bitsize = GET_MODE_BITSIZE (mode); + if (SCALAR_INT_MODE_P (mode) && bitsize <= MAX_FIXED_MODE_SIZE) + return mode; + + /* Reuse the sanity checks from int_mode_for_mode. */ + gcc_checking_assert ((int_mode_for_mode (mode), true)); + + /* Try to replace complex modes with complex modes. In general we + expect both components to be processed independently, so we only + care whether there is a register for the inner mode. */ + if (COMPLEX_MODE_P (mode)) + { + enum machine_mode trial = mode; + if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT) + trial = mode_for_size (bitsize, MODE_COMPLEX_INT, false); + if (trial != BLKmode + && have_regs_of_mode[GET_MODE_INNER (trial)]) + return trial; + } + + /* Try to replace vector modes with vector modes. Also try using vector + modes if an integer mode would be too big. */ + if (VECTOR_MODE_P (mode) || bitsize > MAX_FIXED_MODE_SIZE) + { + enum machine_mode trial = mode; + if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT) + trial = mode_for_size (bitsize, MODE_VECTOR_INT, 0); + if (trial != BLKmode + && have_regs_of_mode[trial] + && targetm.vector_mode_supported_p (trial)) + return trial; + } + + /* Otherwise fall back on integers while honoring MAX_FIXED_MODE_SIZE. */ + return mode_for_size (bitsize, MODE_INT, true); +} + +/* Find a type that can be used for efficient bitwise operations on MODE. + Return null if no such mode exists. */ + +tree +bitwise_type_for_mode (enum machine_mode mode) +{ + mode = bitwise_mode_for_mode (mode); + if (mode == BLKmode) + return NULL_TREE; + + unsigned int inner_size = GET_MODE_UNIT_BITSIZE (mode); + tree inner_type = build_nonstandard_integer_type (inner_size, true); + + if (VECTOR_MODE_P (mode)) + return build_vector_type_for_mode (inner_type, mode); + + if (COMPLEX_MODE_P (mode)) + return build_complex_type (inner_type); + + gcc_checking_assert (GET_MODE_INNER (mode) == VOIDmode); + return inner_type; +} + /* Find a mode that is suitable for representing a vector with NUNITS elements of mode INNERMODE. Returns BLKmode if there is no suitable mode. */ diff --git a/gcc/stor-layout.h b/gcc/stor-layout.h index 74a2c6c4412..e2f800d3b76 100644 --- a/gcc/stor-layout.h +++ b/gcc/stor-layout.h @@ -98,6 +98,8 @@ extern tree make_unsigned_type (int); mode_for_size, but is passed a tree. */ extern enum machine_mode mode_for_size_tree (const_tree, enum mode_class, int); +extern tree bitwise_type_for_mode (enum machine_mode); + /* Given a VAR_DECL, PARM_DECL or RESULT_DECL, clears the results of a previous call to layout_decl and calls it again. */ extern void relayout_decl (tree); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a721c7b7b05..53f5e27d946 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-04-22 Richard Sandiford <rdsandiford@googlemail.com> + + * gcc.dg/memcpy-5.c: New test. + 2014-04-22 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> * gcc.c-torture/compile/pr28865.c: Remove dg-xfail-if. diff --git a/gcc/testsuite/gcc.dg/memcpy-5.c b/gcc/testsuite/gcc.dg/memcpy-5.c new file mode 100644 index 00000000000..dc5afed1907 --- /dev/null +++ b/gcc/testsuite/gcc.dg/memcpy-5.c @@ -0,0 +1,27 @@ +/* { dg-options "-O -fdump-tree-optimized" } */ + +extern void *memcpy (void *, const void *, __SIZE_TYPE__); + +#define TEST(NAME, TYPE) \ + TYPE NAME##x; \ + char NAME##y[sizeof (NAME##x)] __attribute__((aligned (__alignof__ (NAME##x)))); \ + void NAME (void) { memcpy (&NAME##x, &NAME##y, sizeof (NAME##x)); } + +TEST (f, float); +TEST (d, double); +TEST (ld, long double); +TEST (cf, _Complex float); +TEST (cd, _Complex double); +TEST (cld, _Complex long double); +TEST (d8f, float __attribute__((vector_size (8)))); +TEST (d16f, float __attribute__((vector_size (16)))); +TEST (d32f, float __attribute__((vector_size (32)))); +TEST (d64f, float __attribute__((vector_size (64)))); +TEST (d128f, float __attribute__((vector_size (128)))); +TEST (d16d, double __attribute__((vector_size (16)))); +TEST (d32d, double __attribute__((vector_size (32)))); +TEST (d64d, double __attribute__((vector_size (64)))); +TEST (d128d, double __attribute__((vector_size (128)))); + +/* { dg-final { scan-tree-dump-not "memcpy" "optimized" { target x86_64-*-* } } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ |