Skip to content

Commit

Permalink
[libc++] Replace __compressed_pair with [[no_unique_address]]
Browse files Browse the repository at this point in the history
  • Loading branch information
philnik777 committed Jun 24, 2024
1 parent e6ec366 commit 5d0b99d
Show file tree
Hide file tree
Showing 21 changed files with 652 additions and 600 deletions.
3 changes: 3 additions & 0 deletions libcxx/docs/ReleaseNotes/19.rst
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ ABI Affecting Changes
``random_device`` could throw a ``system_error`` with this value. It now
throws ``ENOMSG``.

- The internal structure ``__compressed_pair`` has been replaced with ``[[no_unique_address]]``. This change results in
empty final types being placed at the beginning of the object instead of where the beginning of the
``__compressed_pair`` subobject was. This is only observable by checking the address of the subobject.

Build System Changes
--------------------
Expand Down
77 changes: 77 additions & 0 deletions libcxx/docs/ReleaseNotes/20.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
===========================================
Libc++ 20.0.0 (In-Progress) Release Notes
===========================================

.. contents::
:local:
:depth: 2

Written by the `Libc++ Team <https://libcxx.llvm.org>`_

.. warning::

These are in-progress notes for the upcoming libc++ 20.0.0 release.
Release notes for previous releases can be found on
`the Download Page <https://releases.llvm.org/download.html>`_.

Introduction
============

This document contains the release notes for the libc++ C++ Standard Library,
part of the LLVM Compiler Infrastructure, release 19.0.0. Here we describe the
status of libc++ in some detail, including major improvements from the previous
release and new feature work. For the general LLVM release notes, see `the LLVM
documentation <https://llvm.org/docs/ReleaseNotes.html>`_. All LLVM releases may
be downloaded from the `LLVM releases web site <https://llvm.org/releases/>`_.

For more information about libc++, please see the `Libc++ Web Site
<https://libcxx.llvm.org>`_ or the `LLVM Web Site <https://llvm.org>`_.

Note that if you are reading this file from a Git checkout or the
main Libc++ web page, this document applies to the *next* release, not
the current one. To see the release notes for a specific release, please
see the `releases page <https://llvm.org/releases/>`_.

What's New in Libc++ 20.0.0?
==============================

Implemented Papers
------------------

Improvements and New Features
-----------------------------

- The internal structure ``__compressed_pair`` has been replaced with ``[[no_unique_address]]``, resulting in reduced
compile times and smaller debug information as well as better code gen if optimizations are disabled.

Deprecations and Removals
-------------------------

- TODO: The ``LIBCXX_ENABLE_ASSERTIONS`` CMake variable and the ``_LIBCPP_ENABLE_ASSERTIONS`` macro that were used to
enable the safe mode will be removed in LLVM 20.

Upcoming Deprecations and Removals
----------------------------------

LLVM 21
~~~~~~~
TODO


ABI Affecting Changes
---------------------

- The internal structure ``__compressed_pair`` has been replaced with ``[[no_unique_address]]``. This change results in
empty final types being placed at the beginning of the object instead of where the beginning of the
``__compressed_pair`` subobject was. This is only observable by checking the address of the subobject.

Build System Changes
--------------------

- The ``LIBCXX_EXECUTOR`` and ``LIBCXXABI_EXECUTOR`` CMake variables have been removed. Please
set ``LIBCXX_TEST_PARAMS`` to ``executor=<...>`` instead.

- The Cmake variable ``LIBCXX_ENABLE_CLANG_TIDY`` has been removed. The build system has been changed
to automatically detect the presence of ``clang-tidy`` and the required ``Clang`` libraries.

- The CMake options ``LIBCXX_INSTALL_MODULES`` now defaults to ``ON``.
1 change: 1 addition & 0 deletions libcxx/include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)
# define _LIBCPP_CONCAT3(X, Y, Z) _LIBCPP_CONCAT(X, _LIBCPP_CONCAT(Y, Z))

# if __STDC_HOSTED__ == 0
# define _LIBCPP_FREESTANDING
Expand Down
7 changes: 7 additions & 0 deletions libcxx/include/__configuration/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW
// Dont' add an inline namespace for `std::filesystem`
# define _LIBCPP_ABI_NO_FILESYSTEM_INLINE_NAMESPACE
// Historically, libc++ used a type called `__compressed_pair` to reduce storage need in cases of empty types (e.g. an
// empty allocator in std::vector). We switched to using `[[no_unique_address]]`. However, for ABI compatibility reasons
// we had to add artificial padding in a few places.
//
// This setting disables the addition of such artificial padding, leading to a more optimal
// representation for several types.
# define _LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING
#elif _LIBCPP_ABI_VERSION == 1
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
// Enable compiling copies of now inline methods into the dylib to support
Expand Down
27 changes: 14 additions & 13 deletions libcxx/include/__functional/function.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,45 +143,46 @@ class __default_alloc_func;

template <class _Fp, class _Ap, class _Rp, class... _ArgTypes>
class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> {
__compressed_pair<_Fp, _Ap> __f_;
_LIBCPP_COMPRESSED_PAIR(_Fp, __func_, _Ap, __alloc_);

public:
typedef _LIBCPP_NODEBUG _Fp _Target;
typedef _LIBCPP_NODEBUG _Ap _Alloc;

_LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_.first(); }
_LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __func_; }

// WIN32 APIs may define __allocator, so use __get_allocator instead.
_LIBCPP_HIDE_FROM_ABI const _Alloc& __get_allocator() const { return __f_.second(); }
_LIBCPP_HIDE_FROM_ABI const _Alloc& __get_allocator() const { return __alloc_; }

_LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f)
: __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple()) {}
_LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f) : __func_(std::move(__f)), __alloc_() {}

_LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, const _Alloc& __a)
: __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(__a)) {}
_LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, const _Alloc& __a) : __func_(__f), __alloc_(__a) {}

_LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, _Alloc&& __a)
: __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(std::move(__a))) {}
: __func_(__f), __alloc_(std::move(__a)) {}

_LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f, _Alloc&& __a)
: __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple(std::move(__a))) {}
: __func_(std::move(__f)), __alloc_(std::move(__a)) {}

_LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) {
typedef __invoke_void_return_wrapper<_Rp> _Invoker;
return _Invoker::__call(__f_.first(), std::forward<_ArgTypes>(__arg)...);
return _Invoker::__call(__func_, std::forward<_ArgTypes>(__arg)...);
}

_LIBCPP_HIDE_FROM_ABI __alloc_func* __clone() const {
typedef allocator_traits<_Alloc> __alloc_traits;
typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA;
_AA __a(__f_.second());
_AA __a(__alloc_);
typedef __allocator_destructor<_AA> _Dp;
unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a));
::new ((void*)__hold.get()) __alloc_func(__func_, _Alloc(__a));
return __hold.release();
}

_LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
_LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT {
__func_.~_Fp();
__alloc_.~_Alloc();
}

_LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) {
typedef allocator_traits<_Alloc> __alloc_traits;
Expand Down
Loading

0 comments on commit 5d0b99d

Please sign in to comment.