From patchwork Fri Nov 26 23:08:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 48204 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8F7383857C59 for ; Fri, 26 Nov 2021 23:11:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8F7383857C59 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1637968265; bh=wdovyDcO/ZWprcLAIKVe9QKyRQjsuVx9PKVinGGf8jw=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=GQ4fPysHSsmn7QMv03oziq3uzbUVDsYd3u4+5ieC23Tgrk3wM8a3yBVGF7ybNlxRn 1zLPogmQpey4VWv37cVpSL4LtU48Lat8mB4iz1xorODGhf12D6m8fQ5JGkeSNXBew9 DYhzqpciyOFyS1pTkvZ4BhZd01OCVLmakkHC1BTE= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id D2828385781C for ; Fri, 26 Nov 2021 23:08:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D2828385781C Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-126-ZFVqNoP_NgybGD-lLOJKRA-1; Fri, 26 Nov 2021 18:08:45 -0500 X-MC-Unique: ZFVqNoP_NgybGD-lLOJKRA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 843941006AA0; Fri, 26 Nov 2021 23:08:44 +0000 (UTC) Received: from localhost (unknown [10.33.36.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 35FB510016FC; Fri, 26 Nov 2021 23:08:44 +0000 (UTC) To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Fix trivial relocation for constexpr std::vector Date: Fri, 26 Nov 2021 23:08:43 +0000 Message-Id: <20211126230843.1843602-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-14.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=unavailable autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jonathan Wakely via Gcc-patches From: Jonathan Wakely Reply-To: Jonathan Wakely Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Tested x86_64-linux, pushed to trunk. When implementing constexpr std::vector I added a check for constant evaluation in vector::_S_use_relocate(), so that we would not try to relocate trivial objects by using memmove. But I put it in the constexpr function that decides whether to relocate or not, and calls to that function are always constant evaluated. This had the effect of disabling relocation entirely, even in non-constexpr vectors. This removes the check in _S_use_relocate() and modifies the actual relocation algorithm, __relocate_a_1, to use the non-trivial implementation instead of memmove when called during constant evaluation. libstdc++-v3/ChangeLog: * include/bits/stl_uninitialized.h (__relocate_a_1): Do not use memmove during constant evaluation. * include/bits/stl_vector.h (vector::_S_use_relocate()): Do not check is_constant_evaluated in always-constexpr function. --- libstdc++-v3/include/bits/stl_uninitialized.h | 45 ++++++++++++------- libstdc++-v3/include/bits/stl_vector.h | 4 -- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index 673f6a07675..f2786c5a461 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -1051,6 +1051,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @cond undocumented template + _GLIBCXX20_CONSTEXPR inline void __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig, _Allocator& __alloc) @@ -1070,18 +1071,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_bitwise_relocatable : is_trivial<_Tp> { }; - template - _GLIBCXX20_CONSTEXPR - inline __enable_if_t::value, _Tp*> - __relocate_a_1(_Tp* __first, _Tp* __last, - _Tp* __result, allocator<_Up>&) noexcept - { - ptrdiff_t __count = __last - __first; - if (__count > 0) - __builtin_memmove(__result, __first, __count * sizeof(_Tp)); - return __result + __count; - } - template _GLIBCXX20_CONSTEXPR @@ -1105,6 +1094,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __cur; } + template + _GLIBCXX20_CONSTEXPR + inline __enable_if_t::value, _Tp*> + __relocate_a_1(_Tp* __first, _Tp* __last, + _Tp* __result, + [[__maybe_unused__]] allocator<_Up>& __alloc) noexcept + { + ptrdiff_t __count = __last - __first; + if (__count > 0) + { +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + { + // Can't use memmove. Wrap the pointer so that __relocate_a_1 + // resolves to the non-trivial overload above. + __gnu_cxx::__normal_iterator<_Tp*, void> __out(__result); + __out = std::__relocate_a_1(__first, __last, __out, __alloc); + return __out.base(); + } +#endif + __builtin_memmove(__result, __first, __count * sizeof(_Tp)); + } + return __result + __count; + } + + template _GLIBCXX20_CONSTEXPR @@ -1115,9 +1130,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::__niter_base(__last), std::__niter_base(__result), __alloc))) { - return __relocate_a_1(std::__niter_base(__first), - std::__niter_base(__last), - std::__niter_base(__result), __alloc); + return std::__relocate_a_1(std::__niter_base(__first), + std::__niter_base(__last), + std::__niter_base(__result), __alloc); } /// @endcond diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index bd15b6bd8a8..4587757637e 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -475,10 +475,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER static constexpr bool _S_use_relocate() { -#if __cplusplus >= 202002L && __has_builtin(__builtin_is_constant_evaluated) - if (__builtin_is_constant_evaluated()) - return false; // Cannot use memcpy in constant evaluation contexts. -#endif // Instantiating std::__relocate_a might cause an error outside the // immediate context (in __relocate_object_a's noexcept-specifier), // so only do it if we know the type can be move-inserted into *this.