This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PR 80293] Don't totally-sRA char arrays


Hi,

the patch below is an attempt to deal with PR 80293 as non-invasively
as possible.  Basically, it switches off total SRA scalarization of
any local aggregates which contains an array of elements that have one
byte (or less).

The logic behind this is that accessing such arrays element-wise
usually results in poor code and that such char arrays are often used
for non-statically-typed content anyway, and we do not want to copy
that byte per byte.

Alan, do you think this could impact your constant pool scalarization
too severely?

Richi, if you or Alan does not object in a few days, I'd like to
commit this in time for gcc7.  It has passed bootstrap and testing on
x86_64-linux (but the constant pool SRA work was aimed primarily at
ARM).

Thanks,

Martin


2017-04-10  Martin Jambor  <mjambor@suse.cz>

	* tree-sra.c (scalarizable_type_p): Make char arrays not totally
	scalarizable.

testsuite/
	* g++.dg/tree-ssa/pr80293.C: New test.
---
 gcc/testsuite/g++.dg/tree-ssa/pr80293.C | 45 +++++++++++++++++++++++++++++++++
 gcc/tree-sra.c                          |  2 +-
 2 files changed, 46 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr80293.C

diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr80293.C b/gcc/testsuite/g++.dg/tree-ssa/pr80293.C
new file mode 100644
index 00000000000..7faf35ae983
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr80293.C
@@ -0,0 +1,45 @@
+// { dg-do compile }
+// { dg-options "-O2 -std=gnu++11 -fdump-tree-optimized" } */
+
+#include <array>
+
+// Return a copy of the underlying memory of an arbitrary value.
+template <
+    typename T,
+    typename = typename std::enable_if<std::is_trivially_copyable<T>::value>::type
+>
+auto getMem(
+    T const & value
+) -> std::array<char, sizeof(T)> {
+    auto ret = std::array<char, sizeof(T)>{};
+    __builtin_memcpy(ret.data(), &value, sizeof(T));
+    return ret;
+}
+
+template <
+    typename T,
+    typename = typename std::enable_if<std::is_trivially_copyable<T>::value>::type
+>
+auto fromMem(
+    std::array<char, sizeof(T)> const & buf
+) -> T {
+    auto ret = T{};
+    __builtin_memcpy(&ret, buf.data(), sizeof(T));
+    return ret;
+}
+
+double foo1(std::uint64_t arg) {
+    return fromMem<double>(getMem(arg));
+}
+
+double foo2(std::uint64_t arg) {
+    return *reinterpret_cast<double*>(&arg);
+}
+
+double foo3(std::uint64_t arg) {
+    double ret;
+    __builtin_memcpy(&ret, &arg, sizeof(arg));
+    return ret;
+}
+
+// { dg-final { scan-tree-dump-not "BIT_FIELD_REF" "optimized" } }
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 02453d3ed9a..cbe9e862a2f 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -981,7 +981,7 @@ scalarizable_type_p (tree type)
       if (TYPE_DOMAIN (type) == NULL_TREE
 	  || !tree_fits_shwi_p (TYPE_SIZE (type))
 	  || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (type)))
-	  || (tree_to_shwi (TYPE_SIZE (TREE_TYPE (type))) <= 0)
+	  || (tree_to_shwi (TYPE_SIZE (TREE_TYPE (type))) <= BITS_PER_UNIT)
 	  || !tree_fits_shwi_p (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
 	return false;
       if (tree_to_shwi (TYPE_SIZE (type)) == 0
-- 
2.12.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]