aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamar Christina <tamar.christina@arm.com>2018-08-16 17:05:19 +0000
committerTamar Christina <tnfchris@gcc.gnu.org>2018-08-16 17:05:19 +0000
commit012d429b84046483721291425c9fcdbd167bbaf4 (patch)
tree95b131a8ef283f12cbd33ef4816f030a99581805
parent450f33d6ba630730e86ebabb361651e00ac7741f (diff)
downloadgcc-012d429b84046483721291425c9fcdbd167bbaf4.zip
gcc-012d429b84046483721291425c9fcdbd167bbaf4.tar.gz
gcc-012d429b84046483721291425c9fcdbd167bbaf4.tar.bz2
Allow larger copies when not slow_unaligned_access and no padding.
This allows copy_blkmode_to_reg to perform larger copies when it is safe to do so by calculating the bitsize per iteration doing the maximum copy allowed that does not read more than the amount of bits left to copy. Strictly speaking, this copying is only done if: 1. the target supports fast unaligned access 2. no padding is being used. This should avoid the issues of the first patch (PR85123) but still work for targets that are safe to do so. Original patch https://gcc.gnu.org/ml/gcc-patches/2017-11/msg01088.html Previous respin https://gcc.gnu.org/ml/gcc-patches/2018-04/msg00239.html gcc/ 2018-08-16 Tamar Christina <tamar.christina@arm.com> * expr.c (copy_blkmode_to_reg): Perform larger copies when safe. From-SVN: r263594
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/expr.c21
2 files changed, 25 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d913d7d..6296966 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2018-08-16 Tamar Christina <tamar.christina@arm.com>
+
+ * expr.c (copy_blkmode_to_reg): Perform larger copies when safe.
+
2018-08-16 Matthew Malcomson <matthew.malcomson@arm.com>
* doc/rtl.texi: Replace old RTX class names with new names.
diff --git a/gcc/expr.c b/gcc/expr.c
index de6709d..e8a4f88 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2767,6 +2767,7 @@ copy_blkmode_to_reg (machine_mode mode_in, tree src)
/* No current ABI uses variable-sized modes to pass a BLKmnode type. */
fixed_size_mode mode = as_a <fixed_size_mode> (mode_in);
fixed_size_mode dst_mode;
+ scalar_int_mode min_mode;
gcc_assert (TYPE_MODE (TREE_TYPE (src)) == BLKmode);
@@ -2796,6 +2797,7 @@ copy_blkmode_to_reg (machine_mode mode_in, tree src)
n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
dst_words = XALLOCAVEC (rtx, n_regs);
bitsize = MIN (TYPE_ALIGN (TREE_TYPE (src)), BITS_PER_WORD);
+ min_mode = smallest_int_mode_for_size (bitsize);
/* Copy the structure BITSIZE bits at a time. */
for (bitpos = 0, xbitpos = padding_correction;
@@ -2816,6 +2818,25 @@ copy_blkmode_to_reg (machine_mode mode_in, tree src)
emit_move_insn (dst_word, CONST0_RTX (word_mode));
}
+ /* Find the largest integer mode that can be used to copy all or as
+ many bits as possible of the structure if the target supports larger
+ copies. There are too many corner cases here w.r.t to alignments on
+ the read/writes. So if there is any padding just use single byte
+ operations. */
+ opt_scalar_int_mode mode_iter;
+ if (padding_correction == 0 && !STRICT_ALIGNMENT)
+ {
+ FOR_EACH_MODE_FROM (mode_iter, min_mode)
+ {
+ unsigned int msize = GET_MODE_BITSIZE (mode_iter.require ());
+ if (msize <= ((bytes * BITS_PER_UNIT) - bitpos)
+ && msize <= BITS_PER_WORD)
+ bitsize = msize;
+ else
+ break;
+ }
+ }
+
/* We need a new source operand each time bitpos is on a word
boundary. */
if (bitpos % BITS_PER_WORD == 0)