On Tue, 26 Nov 2024 at 12:08, Jan Hubicka <hubi...@ucw.cz> wrote:
>
> > > diff --git a/libstdc++-v3/include/bits/deque.tcc 
> > > b/libstdc++-v3/include/bits/deque.tcc
> > > index deb010a0ebb..e56cd0b9319 100644
> > > --- a/libstdc++-v3/include/bits/deque.tcc
> > > +++ b/libstdc++-v3/include/bits/deque.tcc
> > > @@ -955,6 +955,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> > >       size_type __new_map_size = this->_M_impl._M_map_size
> > >                                  + std::max(this->_M_impl._M_map_size,
> > >                                             __nodes_to_add) + 2;
> > > +     if (__new_map_size > ((max_size() + __deque_buf_size(sizeof(_Tp)) - 
> > > 1)
> > > +                           / __deque_buf_size(sizeof(_Tp))) * 2)
> > > +       __builtin_unreachable ();
> >
> > I think it's worth avoiding the duplicate call, for -O0 -std=c++98.
> > It makes the line shorter too:
> >
> >   const size_t __bufsz = __deque_buf_size(sizeof(_Tp));
> >   if (__new_map_size > ((max_size() + __bufsz - 1) / __bufsz) * 2)
> >     __builtin_unreachable();
>
> This looks better, in fact that what I inteded with that forgotten
> veriable.  I think __deque_buf_size is a constexpr and gets replaced by
> constant.

No in C++98 (there's no constexpr at all in C++98), and only if used
in a context that requires constant evaluation.

>
> I wonder why "const" is useful here.

Because if you don't initialize a constant expression, then you get a
runtime call to __deque_buf_size instead, which then has to be
inlined.
Using the call to initialize a const size_t ensures it's a constant
expression, and there's nothing for the inliner to do.

> Also I wonder if there is any
> difference between size_type and size_t, or it can be used
> interchangeably?

In general, they are not interchangeable. size_type might comes from
the allocator. But in libstdc++ all our containers (*except*
std::basic_string) just define size_type as a typedef for size_t.
Since __deque_buf_size returns a size_t, that seemed like the right
type (even though they happen to be the same in this code).

> For -O0 we do keep the cmp instruction around, but "optimize away" the
> conditonal jump to unreachable, which is bit odd.  An option would be to
> add ifdef __OPTIMIZE__ guards.
>
> This is updated patch I am testing

OK for trunk if testing succeeds, thanks!


>
> diff --git a/libstdc++-v3/include/bits/deque.tcc 
> b/libstdc++-v3/include/bits/deque.tcc
> index deb010a0ebb..ee03c917a29 100644
> --- a/libstdc++-v3/include/bits/deque.tcc
> +++ b/libstdc++-v3/include/bits/deque.tcc
> @@ -956,6 +956,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>                                      + std::max(this->_M_impl._M_map_size,
>                                                 __nodes_to_add) + 2;
>
> +         const size_t __bufsz = __deque_buf_size(sizeof(_Tp));
> +         if (__new_map_size > ((max_size() + __bufsz - 1) / __bufsz) * 2)
> +           __builtin_unreachable();
> +
>           _Map_pointer __new_map = this->_M_allocate_map(__new_map_size);
>           __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
>                          + (__add_at_front ? __nodes_to_add : 0);
> diff --git a/libstdc++-v3/include/bits/stl_deque.h 
> b/libstdc++-v3/include/bits/stl_deque.h
> index c617933bd81..dd1212793de 100644
> --- a/libstdc++-v3/include/bits/stl_deque.h
> +++ b/libstdc++-v3/include/bits/stl_deque.h
> @@ -1266,7 +1266,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>        _GLIBCXX_NODISCARD
>        size_type
>        size() const _GLIBCXX_NOEXCEPT
> -      { return this->_M_impl._M_finish - this->_M_impl._M_start; }
> +      {
> +       size_type __sz = this->_M_impl._M_finish - this->_M_impl._M_start;
> +       if (__sz > max_size ())
> +         __builtin_unreachable ();
> +       return __sz;
> +      }
>
>        /**  Returns the size() of the largest possible %deque.  */
>        _GLIBCXX_NODISCARD
>

Reply via email to