[clang] Mark `trivial_abi` types as "trivially relocatable".
authorDevin Jeanpierre <jeanpierreda@google.com>
Thu, 3 Feb 2022 01:20:11 +0000 (17:20 -0800)
committerRichard Smith <richard@metafoo.co.uk>
Thu, 3 Feb 2022 01:42:20 +0000 (17:42 -0800)
commit19aa2db023c0128913da223d4fb02c474541ee22
tree17aacf8cecb69d97a89ed831c819154d52f25354
parent42c61a5dfcf9f2b78dae6268223f72b15a257962
[clang] Mark `trivial_abi` types as "trivially relocatable".

This change enables library code to skip paired move-construction and destruction for `trivial_abi` types, as if they were trivially-movable and trivially-destructible. This offers an extension to the performance fix offered by `trivial_abi`: rather than only offering trivial-type-like performance for pass-by-value, it also offers it for library code that moves values but not as arguments.

For example, if we use `memcpy` for trivially relocatable types inside of vector reallocation, and mark `unique_ptr` as `trivial_abi` (via `_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI` / `_LIBCPP_ABI_UNSTABLE` / etc.), this would speed up `vector<unique_ptr>::push_back` by 40% on my benchmarks. (Though note that in this case, the compiler could have done this anyway, but happens not to due to the inlining horizon.)

If accepted, I intend to follow up with exactly such changes to library code, including and especially `std::vector`, making them use a trivial relocation operation on trivially relocatable types.

**D50119 and P1144:**

This change is very similar to D50119, which was rejected from Clang. (That change was an implementation of P1144, which is not yet part of the C++ standard.)

The intent of this change, rather than trying to pick a winning proposal for trivial relocation operations, is to extend the behavior of `trivial_abi` in a way that could be made compatible with any such proposal. If P1144 or any similar proposal were accepted, then `trivial_abi`, `__is_trivially_relocatable`, and everything else in this change would be redefined in terms of that.

**Safety:**

It's worth pointing out, specifically, that `trivial_abi` already implies trivial relocatability in a narrow sense: a `trivial_abi` type, when passed by value, has its constructor run in one location, and its destructor run in another, after the type has been trivially relocated (through registers).

Trivial relocatability optimizations could change the number of paired constructor/destructor calls, but this seems unlikely to matter for `trivial_abi` types.

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D114732
clang/docs/LanguageExtensions.rst
clang/include/clang/AST/Type.h
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/TokenKinds.def
clang/lib/AST/Type.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/test/SemaCXX/attr-trivial-abi.cpp
clang/test/SemaCXX/type-traits.cpp
clang/test/SemaObjCXX/arc-type-traits.mm
clang/test/SemaObjCXX/objc-weak-type-traits.mm