From 2c3b1c5f950429c05865c88bc0b4a460d23f5192 Mon Sep 17 00:00:00 2001 From: Thomas Rodgers Date: Fri, 11 Sep 2020 11:55:18 -0700 Subject: [PATCH] libstdc++: Split std::align/assume_aligned to bits/align.h We would like to be able to use std::align and std::assume_aligned without pulling in everything in . libstdc++-v3/ChangeLog: * include/Makefile.am (bits_headers): Add new header. * include/Makefile.in: Regenerate. * include/bits/align.h: New file. * include/std/memory (align): Move definition to bits/align.h. (assume_aligned): Likewise. --- libstdc++-v3/include/Makefile.am | 1 + libstdc++-v3/include/Makefile.in | 1 + libstdc++-v3/include/bits/align.h | 104 ++++++++++++++++++++++++++++++ libstdc++-v3/include/std/memory | 60 +---------------- 4 files changed, 107 insertions(+), 59 deletions(-) create mode 100644 libstdc++-v3/include/bits/align.h diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 1dff3862e35..c9df9a9d6c6 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -96,6 +96,7 @@ bits_srcdir = ${glibcxx_srcdir}/include/bits bits_builddir = ./bits bits_headers = \ ${bits_srcdir}/algorithmfwd.h \ + ${bits_srcdir}/align.h \ ${bits_srcdir}/alloc_traits.h \ ${bits_srcdir}/allocated_ptr.h \ ${bits_srcdir}/allocator.h \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 16371015071..3d86b733ccd 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -442,6 +442,7 @@ bits_srcdir = ${glibcxx_srcdir}/include/bits bits_builddir = ./bits bits_headers = \ ${bits_srcdir}/algorithmfwd.h \ + ${bits_srcdir}/align.h \ ${bits_srcdir}/alloc_traits.h \ ${bits_srcdir}/allocated_ptr.h \ ${bits_srcdir}/allocator.h \ diff --git a/libstdc++-v3/include/bits/align.h b/libstdc++-v3/include/bits/align.h new file mode 100644 index 00000000000..c3267f22934 --- /dev/null +++ b/libstdc++-v3/include/bits/align.h @@ -0,0 +1,104 @@ +// align implementation -*- C++ -*- + +// Copyright (C) 2014-2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file bits/align.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{memory} + */ + +#ifndef _GLIBCXX_ALIGN_H +#define _GLIBCXX_ALIGN_H 1 + +#include + +#include // std::has_single_bit +#include // uintptr_t + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +/** + * @brief Fit aligned storage in buffer. + * @ingroup memory + * + * This function tries to fit @a __size bytes of storage with alignment + * @a __align into the buffer @a __ptr of size @a __space bytes. If such + * a buffer fits then @a __ptr is changed to point to the first byte of the + * aligned storage and @a __space is reduced by the bytes used for alignment. + * + * C++11 20.6.5 [ptr.align] + * + * @param __align A fundamental or extended alignment value. + * @param __size Size of the aligned storage required. + * @param __ptr Pointer to a buffer of @a __space bytes. + * @param __space Size of the buffer pointed to by @a __ptr. + * @return the updated pointer if the aligned storage fits, otherwise nullptr. + * + */ +inline void* +align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept +{ +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + const auto __intptr = reinterpret_cast(__ptr); +#else + // Cannot use std::uintptr_t so assume that std::size_t can be used instead. + static_assert(sizeof(size_t) >= sizeof(void*), + "std::size_t must be a suitable substitute for std::uintptr_t"); + const auto __intptr = reinterpret_cast(__ptr); +#endif + const auto __aligned = (__intptr - 1u + __align) & -__align; + const auto __diff = __aligned - __intptr; + if ((__size + __diff) > __space) + return nullptr; + else + { + __space -= __diff; + return __ptr = reinterpret_cast(__aligned); + } +} + +#if __cplusplus > 201703L +#define __cpp_lib_assume_aligned 201811L + /** @brief Inform the compiler that a pointer is aligned. + * + * @tparam _Align An alignment value (i.e. a power of two) + * @tparam _Tp An object type + * @param __ptr A pointer that is aligned to _Align + * @ingroup memory + */ + template + [[nodiscard,__gnu__::__always_inline__]] + constexpr _Tp* assume_aligned(_Tp* __ptr) + { + static_assert(std::has_single_bit(_Align)); + _GLIBCXX_DEBUG_ASSERT((std::uintptr_t)__ptr % _Align == 0); + return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Align)); + } +#endif // C++2a + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#endif /* _GLIBCXX_ALIGN_H */ diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory index 1e8eebd731c..a56952fb114 100644 --- a/libstdc++-v3/include/std/memory +++ b/libstdc++-v3/include/std/memory @@ -61,6 +61,7 @@ */ #include +#include #include #include #include @@ -101,46 +102,6 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION -/** - * @brief Fit aligned storage in buffer. - * @ingroup memory - * - * This function tries to fit @a __size bytes of storage with alignment - * @a __align into the buffer @a __ptr of size @a __space bytes. If such - * a buffer fits then @a __ptr is changed to point to the first byte of the - * aligned storage and @a __space is reduced by the bytes used for alignment. - * - * C++11 20.6.5 [ptr.align] - * - * @param __align A fundamental or extended alignment value. - * @param __size Size of the aligned storage required. - * @param __ptr Pointer to a buffer of @a __space bytes. - * @param __space Size of the buffer pointed to by @a __ptr. - * @return the updated pointer if the aligned storage fits, otherwise nullptr. - * - */ -inline void* -align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept -{ -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 - const auto __intptr = reinterpret_cast(__ptr); -#else - // Cannot use std::uintptr_t so assume that std::size_t can be used instead. - static_assert(sizeof(size_t) >= sizeof(void*), - "std::size_t must be a suitable substitute for std::uintptr_t"); - const auto __intptr = reinterpret_cast(__ptr); -#endif - const auto __aligned = (__intptr - 1u + __align) & -__align; - const auto __diff = __aligned - __intptr; - if ((__size + __diff) > __space) - return nullptr; - else - { - __space -= __diff; - return __ptr = reinterpret_cast(__aligned); - } -} - /** @defgroup ptr_safety Pointer Safety and Garbage Collection * @ingroup memory * @@ -179,25 +140,6 @@ inline pointer_safety get_pointer_safety() noexcept { return pointer_safety::relaxed; } // @} -#if __cplusplus > 201703L -#define __cpp_lib_assume_aligned 201811L - /** @brief Inform the compiler that a pointer is aligned. - * - * @tparam _Align An alignment value (i.e. a power of two) - * @tparam _Tp An object type - * @param __ptr A pointer that is aligned to _Align - * @ingroup memory - */ - template - [[nodiscard,__gnu__::__always_inline__]] - constexpr _Tp* assume_aligned(_Tp* __ptr) - { - static_assert(std::has_single_bit(_Align)); - _GLIBCXX_DEBUG_ASSERT((std::uintptr_t)__ptr % _Align == 0); - return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Align)); - } -#endif // C++2a - #if __cplusplus > 201703L template struct __is_pair : false_type { }; -- 2.30.2