]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: Enable memcpy optimizations for distinct integral types [PR93059]
authorJonathan Wakely <jwakely@redhat.com>
Thu, 10 Oct 2024 12:36:33 +0000 (13:36 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 14 Oct 2024 09:38:46 +0000 (10:38 +0100)
commit308d19c11e119b2c5abf67778dd0ac8a370e5df7
tree05e64fc53a35f3b7536e4071b2d6759b93dbb117
parentca44eb7f6a33ff3b93e7685606b4fc286ce0fe80
libstdc++: Enable memcpy optimizations for distinct integral types [PR93059]

Currently we only optimize std::copy, std::copy_n etc. to memmove when
the source and destination types are the same. This means that we fail
to optimize copying between distinct 1-byte types, e.g. copying from a
buffer of unsigned char to a buffer of char8_t or vice versa.

This patch adds more partial specializations of the __memcpyable trait
so that we allow memcpy between integers of equal widths. This will
enable memmove for copies between narrow character types and also
between same-width types like int and unsigned.

Enabling the optimization needs to be based on the width of the integer
type, not just the size in bytes. This is because some targets define
non-standard integral types such as __int20 in msp430, which has padding
bits. It would not be safe to memcpy between e.g. __int20 and int32_t,
even though sizeof(__int20) == sizeof(int32_t). A new trait is
introduced to define the width, __memcpyable_integer, and then the
__memcpyable trait compares the widths.

It's safe to copy between signed and unsigned integers of the same
width, because GCC only supports two's complement integers.

I initially though it would be useful to define the specialization
__memcpyable_integer<byte> to enable copying between narrow character
types and std::byte. But that isn't possible with std::copy, because
is_assignable<char&, std::byte> is false. Optimized copies using memmove
will already happen for copying std::byte to std::byte, because
__memcpyable<T*, T*> is true.

libstdc++-v3/ChangeLog:

PR libstdc++/93059
* include/bits/cpp_type_traits.h (__memcpyable): Add partial
specialization for pointers to distinct types.
(__memcpyable_integer): New trait to control which types can use
cross-type memcpy optimizations.
libstdc++-v3/include/bits/cpp_type_traits.h