* [PATCH] libstdc++: Simplify std::valarray initialization helpers
@ 2024-06-20 15:32 Jonathan Wakely
2024-06-25 23:26 ` Jonathan Wakely
0 siblings, 1 reply; 2+ messages in thread
From: Jonathan Wakely @ 2024-06-20 15:32 UTC (permalink / raw)
To: libstdc++, gcc-patches
Tested x86_64-linux.
-- >8 --
Dispatching to partial specializations doesn't really seem to offer much
benefit here. The __is_trivial(T) condition is a compile-time constant
so the untaken branches are dead code and don't cost us anything.
libstdc++-v3/ChangeLog:
* include/bits/valarray_array.h (_Array_default_ctor): Remove.
(__valarray_default_construct): Inline it into here.
(_Array_init_ctor): Remove.
(__valarray_fill_construct): Inline it into here.
(_Array_copy_ctor): Remove.
(__valarray_copy_construct(const T*, const T*, T*)): Inline it
into here.
(__valarray_copy_construct(const T*, size_t, size_t, T*)):
Use _GLIBCXX17_CONSTEXPR for constant condition.
---
libstdc++-v3/include/bits/valarray_array.h | 97 ++++------------------
1 file changed, 18 insertions(+), 79 deletions(-)
diff --git a/libstdc++-v3/include/bits/valarray_array.h b/libstdc++-v3/include/bits/valarray_array.h
index 07c49ce1057..0dc28333f33 100644
--- a/libstdc++-v3/include/bits/valarray_array.h
+++ b/libstdc++-v3/include/bits/valarray_array.h
@@ -62,105 +62,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__valarray_release_memory(void* __p)
{ operator delete(__p); }
- // Turn a raw-memory into an array of _Tp filled with _Tp()
- // This is required in 'valarray<T> v(n);'
- template<typename _Tp, bool>
- struct _Array_default_ctor
- {
- // Please note that this isn't exception safe. But
- // valarrays aren't required to be exception safe.
- inline static void
- _S_do_it(_Tp* __b, _Tp* __e)
- {
- while (__b != __e)
- new(__b++) _Tp();
- }
- };
-
- template<typename _Tp>
- struct _Array_default_ctor<_Tp, true>
- {
- // For trivial types, it suffices to say 'memset()'
- inline static void
- _S_do_it(_Tp* __b, _Tp* __e)
- { __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); }
- };
-
+ // Turn raw-memory into an array of _Tp filled with _Tp().
+ // This is used in `valarray<T> v(n);` and in `valarray<T>::shift(n)`.
template<typename _Tp>
inline void
__valarray_default_construct(_Tp* __b, _Tp* __e)
{
- _Array_default_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e);
+ if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp))
+ __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp));
+ else
+ while (__b != __e)
+ ::new(static_cast<void*>(__b++)) _Tp();
}
// Turn a raw-memory into an array of _Tp filled with __t
// This is the required in valarray<T> v(n, t). Also
// used in valarray<>::resize().
- template<typename _Tp, bool>
- struct _Array_init_ctor
- {
- // Please note that this isn't exception safe. But
- // valarrays aren't required to be exception safe.
- inline static void
- _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t)
- {
- while (__b != __e)
- new(__b++) _Tp(__t);
- }
- };
-
- template<typename _Tp>
- struct _Array_init_ctor<_Tp, true>
- {
- inline static void
- _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t)
- {
- while (__b != __e)
- *__b++ = __t;
- }
- };
-
template<typename _Tp>
inline void
__valarray_fill_construct(_Tp* __b, _Tp* __e, const _Tp __t)
{
- _Array_init_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __t);
+ while (__b != __e)
+ ::new(static_cast<void*>(__b++)) _Tp(__t);
}
- //
// copy-construct raw array [__o, *) from plain array [__b, __e)
- // We can't just say 'memcpy()'
- //
- template<typename _Tp, bool>
- struct _Array_copy_ctor
- {
- // Please note that this isn't exception safe. But
- // valarrays aren't required to be exception safe.
- inline static void
- _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o)
- {
- while (__b != __e)
- new(__o++) _Tp(*__b++);
- }
- };
-
- template<typename _Tp>
- struct _Array_copy_ctor<_Tp, true>
- {
- inline static void
- _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o)
- {
- if (__b)
- __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp));
- }
- };
-
template<typename _Tp>
inline void
__valarray_copy_construct(const _Tp* __b, const _Tp* __e,
_Tp* __restrict__ __o)
{
- _Array_copy_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __o);
+ if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp))
+ {
+ if (__b)
+ __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp));
+ }
+ else
+ while (__b != __e)
+ ::new(static_cast<void*>(__o++)) _Tp(*__b++);
}
// copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
@@ -169,7 +108,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
size_t __s, _Tp* __restrict__ __o)
{
- if (__is_trivial(_Tp))
+ if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp))
while (__n--)
{
*__o++ = *__a;
--
2.45.2
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] libstdc++: Simplify std::valarray initialization helpers
2024-06-20 15:32 [PATCH] libstdc++: Simplify std::valarray initialization helpers Jonathan Wakely
@ 2024-06-25 23:26 ` Jonathan Wakely
0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Wakely @ 2024-06-25 23:26 UTC (permalink / raw)
To: libstdc++, gcc-patches
Pushed to trunk.
On Thu, 20 Jun 2024 at 16:34, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> Tested x86_64-linux.
>
> -- >8 --
>
> Dispatching to partial specializations doesn't really seem to offer much
> benefit here. The __is_trivial(T) condition is a compile-time constant
> so the untaken branches are dead code and don't cost us anything.
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/valarray_array.h (_Array_default_ctor): Remove.
> (__valarray_default_construct): Inline it into here.
> (_Array_init_ctor): Remove.
> (__valarray_fill_construct): Inline it into here.
> (_Array_copy_ctor): Remove.
> (__valarray_copy_construct(const T*, const T*, T*)): Inline it
> into here.
> (__valarray_copy_construct(const T*, size_t, size_t, T*)):
> Use _GLIBCXX17_CONSTEXPR for constant condition.
> ---
> libstdc++-v3/include/bits/valarray_array.h | 97 ++++------------------
> 1 file changed, 18 insertions(+), 79 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/valarray_array.h b/libstdc++-v3/include/bits/valarray_array.h
> index 07c49ce1057..0dc28333f33 100644
> --- a/libstdc++-v3/include/bits/valarray_array.h
> +++ b/libstdc++-v3/include/bits/valarray_array.h
> @@ -62,105 +62,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> __valarray_release_memory(void* __p)
> { operator delete(__p); }
>
> - // Turn a raw-memory into an array of _Tp filled with _Tp()
> - // This is required in 'valarray<T> v(n);'
> - template<typename _Tp, bool>
> - struct _Array_default_ctor
> - {
> - // Please note that this isn't exception safe. But
> - // valarrays aren't required to be exception safe.
> - inline static void
> - _S_do_it(_Tp* __b, _Tp* __e)
> - {
> - while (__b != __e)
> - new(__b++) _Tp();
> - }
> - };
> -
> - template<typename _Tp>
> - struct _Array_default_ctor<_Tp, true>
> - {
> - // For trivial types, it suffices to say 'memset()'
> - inline static void
> - _S_do_it(_Tp* __b, _Tp* __e)
> - { __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); }
> - };
> -
> + // Turn raw-memory into an array of _Tp filled with _Tp().
> + // This is used in `valarray<T> v(n);` and in `valarray<T>::shift(n)`.
> template<typename _Tp>
> inline void
> __valarray_default_construct(_Tp* __b, _Tp* __e)
> {
> - _Array_default_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e);
> + if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp))
> + __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp));
> + else
> + while (__b != __e)
> + ::new(static_cast<void*>(__b++)) _Tp();
> }
>
> // Turn a raw-memory into an array of _Tp filled with __t
> // This is the required in valarray<T> v(n, t). Also
> // used in valarray<>::resize().
> - template<typename _Tp, bool>
> - struct _Array_init_ctor
> - {
> - // Please note that this isn't exception safe. But
> - // valarrays aren't required to be exception safe.
> - inline static void
> - _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t)
> - {
> - while (__b != __e)
> - new(__b++) _Tp(__t);
> - }
> - };
> -
> - template<typename _Tp>
> - struct _Array_init_ctor<_Tp, true>
> - {
> - inline static void
> - _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t)
> - {
> - while (__b != __e)
> - *__b++ = __t;
> - }
> - };
> -
> template<typename _Tp>
> inline void
> __valarray_fill_construct(_Tp* __b, _Tp* __e, const _Tp __t)
> {
> - _Array_init_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __t);
> + while (__b != __e)
> + ::new(static_cast<void*>(__b++)) _Tp(__t);
> }
>
> - //
> // copy-construct raw array [__o, *) from plain array [__b, __e)
> - // We can't just say 'memcpy()'
> - //
> - template<typename _Tp, bool>
> - struct _Array_copy_ctor
> - {
> - // Please note that this isn't exception safe. But
> - // valarrays aren't required to be exception safe.
> - inline static void
> - _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o)
> - {
> - while (__b != __e)
> - new(__o++) _Tp(*__b++);
> - }
> - };
> -
> - template<typename _Tp>
> - struct _Array_copy_ctor<_Tp, true>
> - {
> - inline static void
> - _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o)
> - {
> - if (__b)
> - __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp));
> - }
> - };
> -
> template<typename _Tp>
> inline void
> __valarray_copy_construct(const _Tp* __b, const _Tp* __e,
> _Tp* __restrict__ __o)
> {
> - _Array_copy_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __o);
> + if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp))
> + {
> + if (__b)
> + __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp));
> + }
> + else
> + while (__b != __e)
> + ::new(static_cast<void*>(__o++)) _Tp(*__b++);
> }
>
> // copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
> @@ -169,7 +108,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
> size_t __s, _Tp* __restrict__ __o)
> {
> - if (__is_trivial(_Tp))
> + if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp))
> while (__n--)
> {
> *__o++ = *__a;
> --
> 2.45.2
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-06-25 23:26 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-20 15:32 [PATCH] libstdc++: Simplify std::valarray initialization helpers Jonathan Wakely
2024-06-25 23:26 ` Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).