From: Luc Grosheintz <luc.groshei...@gmail.com>

In mdspan related code involving static extents, often the IndexType is
part of the template parameters, even though it's not needed.

This commit extracts the parts of _ExtentsStorage not related to
IndexType into a separate class _StaticExtents.

It also prefers passing the array of static extents, instead of the
whole extents object where possible.

The size of an object file compiled with -O2 that instantiates
  Layout::mapping<extents<IndexType, Indices...>::stride
  Layout::mapping<extents<IndexType, Indices...>::required_span_size
for the product of
  - eight IndexTypes
  - three Layouts,
  - nine choices of Indices...
decreases by 19% from 69.2kB to 55.8kB.

libstdc++-v3/ChangeLog:

        * include/std/mdspan (__mdspan::_StaticExtents): Extract non IndexType
        related code from _ExtentsStorage.
        (__mdspan::_ExtentsStorage): Use _StaticExtents.
        (__mdspan::__static_extents): Return reference to NTTP of 
_StaticExtents.
        (__mdspan::__contains_zero): New overload.
        (__mdspan::__exts_prod, __mdspan::__static_quotient): Use span to avoid
        copying __sta_exts.

Reviewed-by: Tomasz Kamiński <tkami...@redhat.com>
Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com>
---
v3 adds following changes:
 * updated __sta_exts variable to span, to preserve old behavior
 * do not use braces to construct span
 * __contains_zero for array uses dynamically sized span

LGTM.

 libstdc++-v3/include/std/mdspan | 56 ++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 19 deletions(-)

diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan
index 5e79d4bfb59..08e6b8ff518 100644
--- a/libstdc++-v3/include/std/mdspan
+++ b/libstdc++-v3/include/std/mdspan
@@ -49,19 +49,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
   namespace __mdspan
   {
-    template<typename _IndexType, array _Extents>
-      class _ExtentsStorage
+    template<array _Extents>
+      class _StaticExtents
       {
       public:
        static consteval bool
        _S_is_dyn(size_t __ext) noexcept
        { return __ext == dynamic_extent; }
 
-       template<typename _OIndexType>
-         static constexpr _IndexType
-         _S_int_cast(const _OIndexType& __other) noexcept
-         { return _IndexType(__other); }
-
        static constexpr size_t _S_rank = _Extents.size();
 
        // For __r in [0, _S_rank], _S_dynamic_index[__r] is the number
@@ -99,6 +94,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        static constexpr size_t
        _S_static_extent(size_t __r) noexcept
        { return _Extents[__r]; }
+      };
+
+    template<typename _IndexType, array _Extents>
+      class _ExtentsStorage : public _StaticExtents<_Extents>
+      {
+      private:
+       using _S_base = _StaticExtents<_Extents>;
+
+      public:
+       using _S_base::_S_rank;
+       using _S_base::_S_rank_dynamic;
+       using _S_base::_S_dynamic_index;
+       using _S_base::_S_dynamic_index_inv;
+
+       template<typename _OIndexType>
+         static constexpr _IndexType
+         _S_int_cast(const _OIndexType& __other) noexcept
+         { return _IndexType(__other); }
 
        constexpr _IndexType
        _M_extent(size_t __r) const noexcept
@@ -157,9 +170,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              { return __exts[__i]; });
          }
 
-       static constexpr span<const size_t>
-       _S_static_extents(size_t __begin, size_t __end) noexcept
-       { return {_Extents.data() + __begin, _Extents.data() + __end}; }
+       static constexpr const array<size_t, _S_rank>&
+       _S_static_extents() noexcept
+       { return _Extents; }
 
        constexpr span<const _IndexType>
        _M_dynamic_extents(size_t __begin, size_t __end) const noexcept
@@ -185,10 +198,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        || _Extent <= numeric_limits<_IndexType>::max();
 
     template<typename _Extents>
-      constexpr span<const size_t>
-      __static_extents(size_t __begin = 0, size_t __end = _Extents::rank())
-      noexcept
-      { return _Extents::_S_storage::_S_static_extents(__begin, __end); }
+      constexpr const array<size_t, _Extents::rank()>&
+      __static_extents() noexcept
+      { return _Extents::_S_storage::_S_static_extents(); }
 
     template<typename _Extents>
       constexpr span<const typename _Extents::index_type>
@@ -314,8 +326,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        }
 
     private:
-      friend span<const size_t>
-      __mdspan::__static_extents<extents>(size_t, size_t);
+      friend const array<size_t, rank()>&
+      __mdspan::__static_extents<extents>();
 
       friend span<const index_type>
       __mdspan::__dynamic_extents<extents>(const extents&, size_t, size_t);
@@ -340,6 +352,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        return false;
       }
 
+    template<typename _Tp, size_t _Nm>
+      consteval bool
+      __contains_zero(const array<_Tp, _Nm>& __exts) noexcept
+      { return __contains_zero(span<const _Tp>(__exts)); }
+
     template<typename _Extents>
       constexpr bool
       __empty(const _Extents& __exts) noexcept
@@ -371,8 +388,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        size_t __ret = 1;
        if constexpr (_Extents::rank_dynamic() != _Extents::rank())
          {
-           auto __sta_exts = __static_extents<_Extents>(__begin, __end);
-           __ret = __static_extents_prod(__sta_exts);
+           std::span<const size_t> __sta_exts = __static_extents<_Extents>();
+           __ret = __static_extents_prod(__sta_exts.subspan(__begin,
+                                                            __end - __begin));
            if (__ret == 0)
              return 0;
          }
@@ -465,7 +483,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       consteval _IndexType
       __static_quotient(_IndexType __nom = numeric_limits<_IndexType>::max())
       {
-       auto __sta_exts = __static_extents<_Extents>();
+       std::span<const size_t> __sta_exts = __static_extents<_Extents>();
        for (auto __factor : __sta_exts)
          {
            if (__factor != dynamic_extent)
-- 
2.49.0

Reply via email to