From patchwork Fri Jun 4 17:02:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim Adye X-Patchwork-Id: 1487966 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FxTcC2m1Dz9s5R for ; Sat, 5 Jun 2021 03:03:22 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E3889399C8BA for ; Fri, 4 Jun 2021 17:03:19 +0000 (GMT) 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 ESMTP id E585E385140C for ; Fri, 4 Jun 2021 17:02:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E585E385140C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=cern.ch Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-264-6LqXcWgoNY--koOgQoBGAg-1; Fri, 04 Jun 2021 13:02:37 -0400 X-MC-Unique: 6LqXcWgoNY--koOgQoBGAg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8EB13107ACC7; Fri, 4 Jun 2021 17:02:35 +0000 (UTC) Received: from localhost (unknown [10.33.37.1]) by smtp.corp.redhat.com (Postfix) with ESMTP id 122782BFF6; Fri, 4 Jun 2021 17:02:34 +0000 (UTC) Date: Fri, 4 Jun 2021 18:02:34 +0100 From: Tim Adye To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Optimize std::any_cast by replacing indirect call Message-ID: MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jwakely@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-14.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: , Cc: Tim Adye , Axel Naumann Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This significantly improves the performance of std::any_cast, by avoiding an indirect call to the _S_manage function through a function pointer. Before we make that indirect call we've already established that the contained value has the expected type, which means we also know the manager type, and so can call one of its members directly. We also know the precise type in the any::emplace functions, because we've just constructed that type, so we can use the new member there too. That doesn't seem to affect performance, but we might as well use the new _S_access function anyway. Signed-off-by: Tim Adye Signed-off-by: Jonathan Wakely libstdc++-v3/ChangeLog: * include/std/any (any::_Manager::_S_access): New static function to access the contained value. (any::emplace, __any_caster): Use _S_access member of the manager type. Tested powerpc64le-linux. Committed to trunk. This patch was contributed by Tim Adye and accepted in line with the new policy announced in https://gcc.gnu.org/pipermail/gcc/2021-June/236182.html Thanks, Tim! commit f6bb145c0bff19767931d37733be11c8acc6fa00 Author: Tim Adye Date: Fri Jun 4 15:59:38 2021 libstdc++: Optimize std::any_cast by replacing indirect call This significantly improves the performance of std::any_cast, by avoiding an indirect call to the _S_manage function through a function pointer. Before we make that indirect call we've already established that the contained value has the expected type, which means we also know the manager type, and so can call one of its members directly. We also know the precise type in the any::emplace functions, because we've just constructed that type, so we can use the new member there too. That doesn't seem to affect performance, but we might as well use the new _S_access function anyway. Signed-off-by: Tim Adye Signed-off-by: Jonathan Wakely libstdc++-v3/ChangeLog: * include/std/any (any::_Manager::_S_access): New static function to access the contained value. (any::emplace, __any_caster): Use _S_access member of the manager type. diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any index 391e43339a0..21120a9146f 100644 --- a/libstdc++-v3/include/std/any +++ b/libstdc++-v3/include/std/any @@ -263,9 +263,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { using _VTp = decay_t<_Tp>; __do_emplace<_VTp>(std::forward<_Args>(__args)...); - any::_Arg __arg; - this->_M_manager(any::_Op_access, this, &__arg); - return *static_cast<_VTp*>(__arg._M_obj); + return *any::_Manager<_VTp>::_S_access(_M_storage); } /// Emplace with an object created from @p __il and @p __args as @@ -276,9 +274,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { using _VTp = decay_t<_Tp>; __do_emplace<_VTp, _Up>(__il, std::forward<_Args>(__args)...); - any::_Arg __arg; - this->_M_manager(any::_Op_access, this, &__arg); - return *static_cast<_VTp*>(__arg._M_obj); + return *any::_Manager<_VTp>::_S_access(_M_storage); } // modifiers @@ -384,6 +380,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void* __addr = &__storage._M_buffer; ::new (__addr) _Tp(std::forward<_Args>(__args)...); } + + static _Tp* + _S_access(const _Storage& __storage) + { + // The contained object is in __storage._M_buffer + const void* __addr = &__storage._M_buffer; + return static_cast<_Tp*>(const_cast(__addr)); + } }; // Manage external contained object. @@ -405,6 +409,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __storage._M_ptr = new _Tp(std::forward<_Args>(__args)...); } + static _Tp* + _S_access(const _Storage& __storage) + { + // The contained object is in *__storage._M_ptr + return static_cast<_Tp*>(__storage._M_ptr); + } }; }; @@ -511,9 +521,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif ) { - any::_Arg __arg; - __any->_M_manager(any::_Op_access, __any, &__arg); - return __arg._M_obj; + return any::_Manager<_Up>::_S_access(__any->_M_storage); } return nullptr; }