[v20,26/40] libstdc++: Optimize is_object trait performance

Message ID 20231016001227.2717180-27-kmatsui@gcc.gnu.org
State Unresolved
Headers
Series Optimize type traits performance |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Ken Matsui Oct. 16, 2023, 12:10 a.m. UTC
  This patch optimizes the performance of the is_object trait by dispatching to
the new __is_function and __is_reference built-in traits.

libstdc++-v3/ChangeLog:
	* include/std/type_traits (is_object): Use __is_function and
	__is_reference built-in traits.
	(is_object_v): Likewise.

Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
---
 libstdc++-v3/include/std/type_traits | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
  

Comments

Patrick Palka Oct. 16, 2023, 6:04 p.m. UTC | #1
On Sun, 15 Oct 2023, Ken Matsui wrote:

> This patch optimizes the performance of the is_object trait by dispatching to
> the new __is_function and __is_reference built-in traits.
> 
> libstdc++-v3/ChangeLog:
> 	* include/std/type_traits (is_object): Use __is_function and
> 	__is_reference built-in traits.
> 	(is_object_v): Likewise.
> 
> Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> ---
>  libstdc++-v3/include/std/type_traits | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
> index bd57488824b..674d398c075 100644
> --- a/libstdc++-v3/include/std/type_traits
> +++ b/libstdc++-v3/include/std/type_traits
> @@ -725,11 +725,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>      { };
>  
>    /// is_object
> +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
> + && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
> +  template<typename _Tp>
> +    struct is_object
> +    : public __bool_constant<!(__is_function(_Tp) || __is_reference(_Tp)
> +                             || is_void<_Tp>::value)>
> +    { };

Since is_object is one of the more commonly used traits, we should
probably just define a built-in for it.  (Either way we'd have to
repeat the logic twice, either once in the frontend and once in
the library, or twice in the library (is_object and is_object_v),
so might as well do the more efficient approach).

> +#else
>    template<typename _Tp>
>      struct is_object
>      : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>,
>                            is_void<_Tp>>>::type
>      { };
> +#endif
>  
>    template<typename>
>      struct is_member_pointer;
> @@ -3305,8 +3314,17 @@ template <typename _Tp>
>    inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
>  template <typename _Tp>
>    inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
> +
> +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
> + && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
> +template <typename _Tp>
> +  inline constexpr bool is_object_v
> +    = !(__is_function(_Tp) || __is_reference(_Tp) || is_void<_Tp>::value);
> +#else
>  template <typename _Tp>
>    inline constexpr bool is_object_v = is_object<_Tp>::value;
> +#endif
> +
>  template <typename _Tp>
>    inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
>  template <typename _Tp>
> -- 
> 2.42.0
> 
>
  
Ken Matsui Oct. 16, 2023, 8:26 p.m. UTC | #2
On Mon, Oct 16, 2023 at 11:04 AM Patrick Palka <ppalka@redhat.com> wrote:
>
> On Sun, 15 Oct 2023, Ken Matsui wrote:
>
> > This patch optimizes the performance of the is_object trait by dispatching to
> > the new __is_function and __is_reference built-in traits.
> >
> > libstdc++-v3/ChangeLog:
> >       * include/std/type_traits (is_object): Use __is_function and
> >       __is_reference built-in traits.
> >       (is_object_v): Likewise.
> >
> > Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> > ---
> >  libstdc++-v3/include/std/type_traits | 18 ++++++++++++++++++
> >  1 file changed, 18 insertions(+)
> >
> > diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
> > index bd57488824b..674d398c075 100644
> > --- a/libstdc++-v3/include/std/type_traits
> > +++ b/libstdc++-v3/include/std/type_traits
> > @@ -725,11 +725,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >      { };
> >
> >    /// is_object
> > +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
> > + && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
> > +  template<typename _Tp>
> > +    struct is_object
> > +    : public __bool_constant<!(__is_function(_Tp) || __is_reference(_Tp)
> > +                             || is_void<_Tp>::value)>
> > +    { };
>
> Since is_object is one of the more commonly used traits, we should
> probably just define a built-in for it.  (Either way we'd have to
> repeat the logic twice, either once in the frontend and once in
> the library, or twice in the library (is_object and is_object_v),
> so might as well do the more efficient approach).
>

Sure, I'll implement it :) Thank you for your review!

> > +#else
> >    template<typename _Tp>
> >      struct is_object
> >      : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>,
> >                            is_void<_Tp>>>::type
> >      { };
> > +#endif
> >
> >    template<typename>
> >      struct is_member_pointer;
> > @@ -3305,8 +3314,17 @@ template <typename _Tp>
> >    inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
> >  template <typename _Tp>
> >    inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
> > +
> > +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
> > + && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
> > +template <typename _Tp>
> > +  inline constexpr bool is_object_v
> > +    = !(__is_function(_Tp) || __is_reference(_Tp) || is_void<_Tp>::value);
> > +#else
> >  template <typename _Tp>
> >    inline constexpr bool is_object_v = is_object<_Tp>::value;
> > +#endif
> > +
> >  template <typename _Tp>
> >    inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
> >  template <typename _Tp>
> > --
> > 2.42.0
> >
> >
>
  

Patch

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index bd57488824b..674d398c075 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -725,11 +725,20 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { };
 
   /// is_object
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
+ && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+  template<typename _Tp>
+    struct is_object
+    : public __bool_constant<!(__is_function(_Tp) || __is_reference(_Tp)
+                             || is_void<_Tp>::value)>
+    { };
+#else
   template<typename _Tp>
     struct is_object
     : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>,
                           is_void<_Tp>>>::type
     { };
+#endif
 
   template<typename>
     struct is_member_pointer;
@@ -3305,8 +3314,17 @@  template <typename _Tp>
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 template <typename _Tp>
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
+ && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+template <typename _Tp>
+  inline constexpr bool is_object_v
+    = !(__is_function(_Tp) || __is_reference(_Tp) || is_void<_Tp>::value);
+#else
 template <typename _Tp>
   inline constexpr bool is_object_v = is_object<_Tp>::value;
+#endif
+
 template <typename _Tp>
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template <typename _Tp>