public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Patrick Palka <ppalka@redhat.com>
To: gcc-patches@gcc.gnu.org
Cc: libstdc++@gcc.gnu.org, Patrick Palka <ppalka@redhat.com>
Subject: [PATCH 4/4] libstdc++: Rearrange some range adaptors' data members
Date: Mon, 28 Sep 2020 00:48:54 -0400	[thread overview]
Message-ID: <20200928044854.46674-4-ppalka@redhat.com> (raw)
In-Reply-To: <20200928044854.46674-1-ppalka@redhat.com>

Since the standard range adaptors are specified to derive from the empty
class view_base, making their first data member store the underlying
view is suboptimal, for if the underlying view also derives from
view_base then the two view_base subobjects will be adjacent, thus
preventing the compiler from applying the empty base optimization to
elide away the storage for these two empty bases.

This patch improves the situation by declaring the _M_base data member
last instead of first in each range adaptor that has more than one data
member, so that the empty base optimization can apply more often.

Tested on x86_64-pc-linux-gnu with and wihout -m32.

libstdc++-v3/ChangeLog:

	* include/std/ranges (filter_view::_M_base): Declare this data
	member last.
	(transform_view::_M_base): Likewise.
	(take_view::_M_base): Likewise.
	(take_while_view::_M_base): Likewise.
	(drop_view::_M_base): Likewise.
	(drop_while_view::_M_base): Likewise.
	(join_view::_M_base): Likewise.
	(split_view::_M_base): Likewise.
	* testsuite/std/ranges/adaptors/sizeof.cc: Adjust expected
	sizes.
---
 libstdc++-v3/include/std/ranges                | 17 ++++++++---------
 .../testsuite/std/ranges/adaptors/sizeof.cc    | 18 +++++++++---------
 2 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 964a2b616a6..6fd8a85c2bf 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -1250,9 +1250,9 @@ namespace views
 	{ return __y.__equal(__x); }
       };
 
-      _Vp _M_base = _Vp();
       [[no_unique_address]] __detail::__box<_Pred> _M_pred;
       [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
+      _Vp _M_base = _Vp();
 
     public:
       filter_view() = default;
@@ -1588,8 +1588,8 @@ namespace views
 	  friend _Sentinel<!_Const>;
 	};
 
-      _Vp _M_base = _Vp();
       [[no_unique_address]] __detail::__box<_Fp> _M_fun;
+      _Vp _M_base = _Vp();
 
     public:
       transform_view() = default;
@@ -1695,8 +1695,8 @@ namespace views
 	  friend _Sentinel<!_Const>;
 	};
 
-      _Vp _M_base = _Vp();
       range_difference_t<_Vp> _M_count = 0;
+      _Vp _M_base = _Vp();
 
     public:
       take_view() = default;
@@ -1842,8 +1842,8 @@ namespace views
 	  friend _Sentinel<!_Const>;
 	};
 
-      _Vp _M_base = _Vp();
       [[no_unique_address]] __detail::__box<_Pred> _M_pred;
+      _Vp _M_base = _Vp();
 
     public:
       take_while_view() = default;
@@ -1902,8 +1902,8 @@ namespace views
     class drop_view : public view_interface<drop_view<_Vp>>
     {
     private:
-      _Vp _M_base = _Vp();
       range_difference_t<_Vp> _M_count = 0;
+      _Vp _M_base = _Vp();
 
       // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
       // both random_access_range and sized_range. Otherwise, cache its result.
@@ -2002,9 +2002,9 @@ namespace views
     class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
     {
     private:
-      _Vp _M_base = _Vp();
       [[no_unique_address]] __detail::__box<_Pred> _M_pred;
       [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
+      _Vp _M_base = _Vp();
 
     public:
       drop_while_view() = default;
@@ -2300,12 +2300,11 @@ namespace views
 	  friend _Sentinel<!_Const>;
 	};
 
-      _Vp _M_base = _Vp();
-
       // XXX: _M_inner is "present only when !is_reference_v<_InnerRange>"
       [[no_unique_address]]
 	__detail::__maybe_present_t<!is_reference_v<_InnerRange>,
 				    views::all_t<_InnerRange>> _M_inner;
+      _Vp _M_base = _Vp();
 
     public:
       join_view() = default;
@@ -2680,8 +2679,8 @@ namespace views
 	  { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
 	};
 
-      _Vp _M_base = _Vp();
       _Pattern _M_pattern = _Pattern();
+      _Vp _M_base = _Vp();
 
       // XXX: _M_current is "present only if !forward_range<V>"
       [[no_unique_address]]
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/sizeof.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/sizeof.cc
index 5fb1ab7e4da..a7f622bb725 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/sizeof.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/sizeof.cc
@@ -33,17 +33,17 @@ using V = ranges::subrange<int*, int*>;
 constexpr auto ptr = sizeof(int*);
 static_assert(sizeof(V) == 2*ptr);
 
-static_assert(sizeof(ranges::take_view<V>) == 4*ptr);
-static_assert(sizeof(ranges::drop_view<V>) == 4*ptr);
+static_assert(sizeof(ranges::take_view<V>) == 3*ptr);
+static_assert(sizeof(ranges::drop_view<V>) == 3*ptr);
 
-static_assert(sizeof(ranges::filter_view<V, decltype(&pred_f)>) == 5*ptr);
-static_assert(sizeof(ranges::take_while_view<V, decltype(&pred_f)>) == 4*ptr);
-static_assert(sizeof(ranges::drop_while_view<V, decltype(&pred_f)>) == 5*ptr);
-static_assert(sizeof(ranges::transform_view<V, decltype(&func_f)>) == 4*ptr);
+static_assert(sizeof(ranges::filter_view<V, decltype(&pred_f)>) == 4*ptr);
+static_assert(sizeof(ranges::take_while_view<V, decltype(&pred_f)>) == 3*ptr);
+static_assert(sizeof(ranges::drop_while_view<V, decltype(&pred_f)>) == 4*ptr);
+static_assert(sizeof(ranges::transform_view<V, decltype(&func_f)>) == 3*ptr);
 
-static_assert(sizeof(ranges::filter_view<V, decltype(pred_l)>) == 4*ptr);
+static_assert(sizeof(ranges::filter_view<V, decltype(pred_l)>) == 3*ptr);
 static_assert(sizeof(ranges::take_while_view<V, decltype(pred_l)>) == 3*ptr);
-static_assert(sizeof(ranges::drop_while_view<V, decltype(pred_l)>) == 4*ptr);
+static_assert(sizeof(ranges::drop_while_view<V, decltype(pred_l)>) == 3*ptr);
 static_assert(sizeof(ranges::transform_view<V, decltype(func_l)>) == 3*ptr);
 
-static_assert(sizeof(ranges::split_view<V, std::string_view>) == 5*ptr);
+static_assert(sizeof(ranges::split_view<V, std::string_view>) == 4*ptr);
-- 
2.28.0.618.g9bc233ae1c


  parent reply	other threads:[~2020-09-28  4:49 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-28  4:48 [PATCH 1/4] libstdc++: Reduce the size of an unbounded iota_view Patrick Palka
2020-09-28  4:48 ` [PATCH 2/4] libstdc++: Reduce the size of a subrange with empty sentinel type Patrick Palka
2020-09-28  9:32   ` Jonathan Wakely
2020-09-28  4:48 ` [PATCH 3/4] libstdc++: Add test that tracks range adaptors' sizes Patrick Palka
2020-09-28  9:32   ` Jonathan Wakely
2020-09-28  4:48 ` Patrick Palka [this message]
2020-09-28  9:34   ` [PATCH 4/4] libstdc++: Rearrange some range adaptors' data members Jonathan Wakely
2020-09-28 13:11     ` Patrick Palka
2020-09-28 15:38       ` Jonathan Wakely
2020-09-28  9:31 ` [PATCH 1/4] libstdc++: Reduce the size of an unbounded iota_view Jonathan Wakely

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200928044854.46674-4-ppalka@redhat.com \
    --to=ppalka@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=libstdc++@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).