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
This commit is contained in:
Tamar Christina 2018-08-16 17:05:19 +00:00 committed by Tamar Christina
parent 450f33d6ba
commit 012d429b84
2 changed files with 25 additions and 0 deletions

View File

@ -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> 2018-08-16 Matthew Malcomson <matthew.malcomson@arm.com>
* doc/rtl.texi: Replace old RTX class names with new names. * doc/rtl.texi: Replace old RTX class names with new names.

View File

@ -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. */ /* 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 mode = as_a <fixed_size_mode> (mode_in);
fixed_size_mode dst_mode; fixed_size_mode dst_mode;
scalar_int_mode min_mode;
gcc_assert (TYPE_MODE (TREE_TYPE (src)) == BLKmode); 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; n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
dst_words = XALLOCAVEC (rtx, n_regs); dst_words = XALLOCAVEC (rtx, n_regs);
bitsize = MIN (TYPE_ALIGN (TREE_TYPE (src)), BITS_PER_WORD); 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. */ /* Copy the structure BITSIZE bits at a time. */
for (bitpos = 0, xbitpos = padding_correction; 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)); 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 /* We need a new source operand each time bitpos is on a word
boundary. */ boundary. */
if (bitpos % BITS_PER_WORD == 0) if (bitpos % BITS_PER_WORD == 0)