summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2014-04-22 12:46:07 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2014-04-22 12:46:07 +0000
commitac875fa40bf5429aff0612943d8c5705c4e11bb5 (patch)
tree6254ef8bed13933fcdfb55163f89625f1932c652
parent3efb5d22322a504342153f3d64f1a3a209c3fe40 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/builtins.c22
-rw-r--r--gcc/machmode.h2
-rw-r--r--gcc/stor-layout.c67
-rw-r--r--gcc/stor-layout.h2
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/memcpy-5.c27
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" } } */