Age | Commit message (Collapse) | Author | Files | Lines |
|
libstdc++-v3/ChangeLog:
* testsuite/28_regex/traits/char/transform_primary.cc: Fix
subclause numbering in references to the standard.
|
|
convert to its rettype [PR118387]
Note, the PR raises another problem.
If on the same testcase the B b; line is removed, we silently synthetize
operator<=> which will crash at runtime due to returning without a return
statement. That is because the standard says that in that case
it should return static_cast<int>(std::strong_ordering::equal);
but I can't find anywhere wording which would say that if that isn't
valid, the function is deleted.
https://eel.is/c++draft/class.compare#class.spaceship-2.2
seems to talk just about cases where there are some members and their
comparison is invalid it is deleted, but here there are none and it
follows
https://eel.is/c++draft/class.compare#class.spaceship-3.sentence-2
So, we synthetize with tf_none, see the static_cast is invalid, don't
add error_mark_node statement silently, but as the function isn't deleted,
we just silently emit it.
Should the standard be amended to say that the operator should be deleted
even if it has no elements and the static cast from
https://eel.is/c++draft/class.compare#class.spaceship-3.sentence-2
On Fri, Jan 10, 2025 at 12:04:53PM -0500, Jason Merrill wrote:
> That seems pretty obviously what we want, and is what the other compilers
> implement.
This patch implements it then.
2025-01-15 Jakub Jelinek <jakub@redhat.com>
PR c++/118387
* method.cc (build_comparison_op): Set bad if
std::strong_ordering::equal doesn't convert to rettype.
* g++.dg/cpp2a/spaceship-err6.C: Expect another error.
* g++.dg/cpp2a/spaceship-synth17.C: Likewise.
* g++.dg/cpp2a/spaceship-synth-neg6.C: Likewise.
* g++.dg/cpp2a/spaceship-synth-neg7.C: New test.
* testsuite/25_algorithms/default_template_value.cc
(Input::operator<=>): Use auto as return type rather than bool.
|
|
|
|
When running tests using the "sim" config, the command is launched in
non-readonly mode and the text retrieved from the expect command will
then replace all LF with CRLF. (The problem can be found in sim_load
where it calls remote_spawn without an input file).
libstdc++-v3/ChangeLog:
* testsuite/27_io/print/1.cc: Allow both LF and CRLF in test.
* testsuite/27_io/print/3.cc: Likewise.
Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
|
|
Test assumes libatomic.a is always available, but for some embedded
targets, there is no libatomic.a and the test thus fail.
libstdc++-v3/ChangeLog:
* testsuite/29_atomics/atomic_float/compare_exchange_padding.cc:
Use effective-target libatomic_available.
Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
|
|
|
|
This fixes warnings like the following during bootstrap:
sparc-sun-solaris2.11/libstdc++-v3/include/bits/atomic_futex.h:324:53: warning: unused parameter ‘__mo’ [-Wunused-parameter]
324 | _M_load_when_equal(unsigned __val, memory_order __mo)
| ~~~~~~~~~~~~~^~~~
libstdc++-v3/ChangeLog:
* include/bits/atomic_futex.h (__atomic_futex_unsigned): Remove
names of unused parameters in non-futex implementation.
|
|
|
|
libstdc++-v3/ChangeLog:
* include/bits/move.h (__addressof, forward, forward_like, move)
(move_if_noexcept, addressof): Add always_inline attribute.
Replace _GLIBCXX_NODISCARD with [[__nodiscard__]].
|
|
libstdc++-v3/ChangeLog:
PR libstdc++/118260
* python/hook.in: Run 'skip' commands for some simple accessor
functions.
|
|
std::to_underlying was missing from the std module introduced in
r15-5366-g7db55c0ba1baaf. This patch adds the missing export for this
utility.
libstdc++-v3/ChangeLog:
PR libstdc++/106852
* src/c++23/std.cc.in (to_underlying): Add.
Signed-off-by: Nicolas Werner <nicolas.werner@hotmail.de>
|
|
The std-clib.cc module definition file assumes that all names are
available unconditionally, but that's not true for all targets. Use the
same preprocessor conditions as are present in the <cxxx> headers.
A similar change is needed in std.cc.in for the <chrono> features that
depend on the SSO std::string, guarded with a __cpp_lib_chrono value
indicating full C++20 support.
The conditions for <cmath> are omitted from this change, as there are a
large number of them. That probably needs to be fixed.
libstdc++-v3/ChangeLog:
PR libstdc++/118177
* src/c++23/std-clib.cc.in: Use preprocessor conditions for
names which are not always defined.
* src/c++23/std.cc.in: Likewise.
|
|
libstdc++-v3/ChangeLog:
* include/std/span: Fix indentation.
|
|
This commit implements P2447R6. The code is straightforward (just one
extra constructor, with constraints and conditional explicit).
I decided to suppress -Winit-list-lifetime because otherwise it would
give too many false positives. The new constructor is meant to be used
as a parameter-passing interface (this is a design choice, see
P2447R6/§2) and, as such, the initializer_list won't dangle despite
GCC's warnings.
The new constructor isn't 100% backwards compatible. A couple of
examples are included in Annex C, but I have also lifted some more
from R4. A new test checks for the old and the new behaviors.
libstdc++-v3/ChangeLog:
* include/bits/version.def: Add the new feature-testing macro.
* include/bits/version.h: Regenerate.
* include/std/span: Add constructor from initializer_list.
* testsuite/23_containers/span/init_list_cons.cc: New test.
* testsuite/23_containers/span/init_list_cons_neg.cc: New test.
Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
|
|
Any std::span<T, N> constructor with a runtime length has a precondition
that the length is equal to N (except when N == std::dynamic_extent).
Currently every constructor with a runtime length does:
if constexpr (extent != dynamic_extent)
__glibcxx_assert(n == extent);
We can move those assertions into the __detail::__extent_storage<N>
constructor so they are only done in one place. To avoid checking the
assertions when we have a constant length we can add a second
constructor which is consteval and takes a integral_constant<size_t, N>
argument. The std::span constructors can pass a size_t for runtime
lengths and a std::integral_constant<size_t, N> for constant lengths
that don't need to be checked.
The __detail::__extent_storage<dynamic_extent> specialization only needs
one constructor, as a std::integral_constant<size_t, N> argument can
implicitly convert to size_t.
For the member functions that return a subspan with a constant extent we
return std::span<T,C>(ptr, C) which is redundant in two ways. Repeating
the constant length C when it's already a template argument is
redundant, and using the std::span(T*, size_t) constructor implies a
runtime length which will do a redundant assertion check. Even though
that assertion won't fail and should be optimized away, it's still
unnecessary code that doesn't need to be instantiated and then optimized
away again. We can avoid that by adding a new private constructor that
only takes a pointer (wrapped in a custom tag struct to avoid
accidentally using that constructor) and automatically sets _M_extent to
the correct value.
libstdc++-v3/ChangeLog:
* include/std/span (__detail::__extent_storage): Check
precondition in constructor. Add consteval constructor for valid
lengths and deleted constructor for invalid constant lengths.
Make member functions always_inline.
(__detail::__span_ptr): New class template.
(span): Adjust constructors to use a std::integral_constant
value for constant lengths. Declare all specializations of
std::span as friends.
(span::first<C>, span::last<C>, span::subspan<O,C>): Use new
private constructor.
(span(__span_ptr<T>)): New private constructor for constant
lengths.
|
|
std::regex builds a cache of equivalence classes by calling
std::regex_traits<char>::transform_primary(c) for every char, which then
calls std::collate<char>::transform which calls strxfrm. On several
targets strxfrm fails for non-ASCII characters. Because strxfrm has no
return value reserved to indicate an error, some implementations return
INT_MAX or SIZE_MAX. This causes std::collate::transform to try to
allocate a huge buffer, which is either very slow or throws
std::bad_alloc. We should check errno after calling strxfrm to detect
errors and then throw a more appropriate exception instead of trying to
allocate a huge buffer.
Unfortunately the std::collate<C>::_M_transform function has a
non-throwing exception specifier, so we can't do the error handling
there.
As well as checking errno, this patch changes std::collate::do_transform
to use __builtin_alloca for small inputs, and to use RAII to deallocate
the buffers used for large inputs.
This change isn't sufficient to fix the three std::regex bugs caused by
the lack of error handling in std::collate::do_transform, we also need
to make std::regex_traits::transform_primary handle exceptions. This
change also attempts to make transform_primary closer to the effects
described in the standard, by not even attempting to use std::collate if
the locale's std::collate facet has been replaced (see PR 118105).
Implementing the correct effects for transform_primary requires RTTI, so
that we don't use some user-defined std::collate facet with unknown
semantics. When -fno-rtti is used transform_primary just returns an
empty string, making equivalence classes unusable in std::basic_regex.
That's not ideal, but I don't have any better ideas.
I'm unsure if std::regex_traits<C>::transform_primary is supposed to
convert the string to lower case or not. The general regex traits
requirements ([re.req] p20) do say "when character case is not
considered" but the specification for the std::regex_traits<char> and
std::regex_traits<wchar_t> specializations ([re.traits] p7) don't say
anything about that.
With the r15-6317-geb339c29ee42aa change, transform_primary is not
called unless the regex actually uses an equivalence class. But using an
equivalence class would still fail (or be incredibly slow) on some
targets. With this commit, equivalence classes should be usable on all
targets, without excessive memory allocations.
Arguably, we should not even try to call transform_primary for any char
values over 127, since they're never valid in locales that use UTF-8 or
7-bit ASCII, and probably for other charsets too. Handling 128
exceptions for every std::regex compilation is very inefficient, but at
least it now works instead of failing with std::bad_alloc, and no longer
allocates 128 x 2GB. Maybe for C++26 we could check the locale's
std::text_encoding and use that to decide whether to cache equivalence
classes for char values over 127.
libstdc++-v3/ChangeLog:
PR libstdc++/85824
PR libstdc++/94409
PR libstdc++/98723
PR libstdc++/118105
* include/bits/locale_classes.tcc (collate::do_transform): Check
errno after calling _M_transform. Use RAII type to manage the
buffer and to restore errno.
* include/bits/regex.h (regex_traits::transform_primary): Handle
exceptions from std::collate::transform and do not try to use
std::collate for user-defined facets.
|
|
The current check for negative times (i.e. before the epoch) only checks
for a negative number of seconds. For a time 1ms before the epoch the
seconds part will be zero, but the futex syscall will still fail with an
EINVAL error. Extend the check to handle this case.
This change adds a redundant check in the headers too, so that we avoid
even calling into the library for negative times. Both checks can be
marked [[unlikely]]. The check in the headers avoids the cost of
splitting the time into seconds and nanoseconds and then making a PLT
call. The check inside the library matches where we were checking
already, and fixes existing binaries that were compiled against older
headers but use a newer libstdc++.so.6 at runtime.
libstdc++-v3/ChangeLog:
PR libstdc++/118093
* include/bits/atomic_futex.h (_M_load_and_test_until_impl):
Return false for times before the epoch.
* src/c++11/futex.cc (_M_futex_wait_until): Extend check for
negative times to check for subsecond times. Add unlikely
attribute.
(_M_futex_wait_until_steady): Likewise.
* testsuite/30_threads/future/members/118093.cc: New test.
|
|
We have several overloads of std::deque::_M_insert_aux, one of which is
variadic and called by std::deque::emplace. With a suitable set of
arguments to emplace, it's possible for one of the non-variadic
_M_insert_aux overloads to be selected by overload resolution, making
emplace ill-formed.
Rename the variadic _M_insert_aux to _M_emplace_aux so that calls to
emplace never select an _M_insert_aux overload. Also add an inline
_M_insert_aux for the const lvalue overload that is called from
insert(const_iterator, const value_type&).
libstdc++-v3/ChangeLog:
PR libstdc++/90389
* include/bits/deque.tcc (_M_insert_aux): Rename variadic
overload to _M_emplace_aux.
* include/bits/stl_deque.h (_M_insert_aux): Define inline.
(_M_emplace_aux): Declare.
* testsuite/23_containers/deque/modifiers/emplace/90389.cc: New
test.
|
|
Also add "@since C++11" to std::move, std::forward etc.
libstdc++-v3/ChangeLog:
* include/bits/move.h (forward, move, move_if_noexcept, addressof):
Add @since to Doxygen comments.
(forward_like): Add Doxygen comment.
|
|
libstdc++-v3/ChangeLog:
* doc/xml/manual/evolution.xml: Replace invalid <variable>
elements with <varname>.
* doc/html/*: Regenerate.
|
|
|
|
|
|
Rotate ChangeLog files for ChangeLogs with yearly cadence.
Also remove empty lines before Form Feed line.
|
|
|
|
Commit 544be2beb1fa in 2019 remove Profile Mode and associated docs.
Now also remove generated HTML files.
libstdc++-v3:
* doc/html/manual/profile_mode.html: Delete.
* doc/html/manual/profile_mode_api.html: Ditto.
* doc/html/manual/profile_mode_cost_model.html: Ditto.
* doc/html/manual/profile_mode_design.html: Ditto.
* doc/html/manual/profile_mode_devel.html: Ditto.
* doc/html/manual/profile_mode_impl.html: Ditto.
|
|
|
|
Commit 544be2beb1fa in 2019 remove Profile Mode and associated docs
including the XML version of profile_mode_diagnostics.html. Somehow
the latter survived until now. Simply delete it as well.
libstdc++-v3:
* doc/html/manual/profile_mode_diagnostics.html: Delete.
|
|
These two long-running tests happened to fail for me when
run in parallel (nprocs - 1) compared to a serial run, for
target mmix on my laptop. The runtime is 3m40s for 3.cc
before this change, and 0.9s afterwards.
* testsuite/std/time/year_month_day/3.cc (test01): Add ifdeffery to
limit the tested dates. For simulators, pass start and end dates
limiting the tested range to 100000 days, centered on days (0).
* testsuite/std/time/year_month_day/4.cc: Ditto.
|
|
|
|
The test used #include "<generator>", so FAILed everywhere with
fatal error: <generator>: No such file or directory
2024-12-28 Jakub Jelinek <jakub@redhat.com>
PR libstdc++/118196
* testsuite/24_iterators/range_generators/pr118196.cc: Include
<generator> rather than "<generator>".
|
|
|
|
libstdc++-v3/ChangeLog:
PR libstdc++/118196
* include/std/generator (generator::operator=(generator)): Add
missing 'return *this;'.
* testsuite/24_iterators/range_generators/pr118196.cc: New test.
|
|
This overload requires
constructible_from<remove_cvref_t<yielded>,
const remove_reference_t<yielded>&>
... but then tries to construct remove_cvref_t<yielded> implicitly,
which means it imposes an additional constraint not in the standard.
libstdc++-v3/ChangeLog:
PR libstdc++/118022
* include/std/generator
(_Promise_erased::yield_value(const _Yielded_deref&)): Don't
implicit-constuct _Yielded_decvref.
* testsuite/24_iterators/range_generators/pr118022.cc: New test.
|
|
|
|
The fancy allocator pointer type support is added to std::map,
std::multimap, std::multiset and std::set through the underlying
std::_Rb_tree class.
To respect ABI a new parralel hierarchy of node types has been added.
This change introduces new class template parameterized on the
allocator's void_pointer type, __rb_tree::_Node_base, and new class
templates parameterized on the allocator's pointer type, __rb_tree::_Node,
__rb_tree::_Iterator. The iterator class template is used for both
iterator and const_iterator. Whether std::_Rb_tree<K, V, KoV, C, A>
should use the old _Rb_tree_node<V> or new __rb_tree::_Node<A::pointer>
type family internally is controlled by a new __rb_tree::_Node_traits
traits template.
Because std::pointer_traits and std::__to_address are not defined for
C++98, there is no way to support fancy pointers in C++98. For C++98 the
_Node_traits traits always choose the old _Rb_tree_node family.
In case anybody is currently using std::_Rb_tree with an allocator that
has a fancy pointer, this change would be an ABI break, because their
std::_Rb_tree instantiations would start to (correctly) use the fancy
pointer type. If the fancy pointer just contains a single pointer and so
has the same size, layout, and object representation as a raw pointer,
the code might still work (despite being an ODR violation). But if their
fancy pointer has a different representation, they would need to
recompile all their code using that allocator with std::_Rb_tree. Because
std::_Rb_tree will never use fancy pointers in C++98 mode, recompiling
everything to use fancy pointers isn't even possible if mixing C++98 and
C++11 code that uses std::_Rb_tree. To alleviate this problem, compiling
with -D_GLIBCXX_USE_ALLOC_PTR_FOR_RB_TREE=0 will force std::_Rb_tree to
have the old, non-conforming behaviour and use raw pointers internally.
For testing purposes, compiling with -D_GLIBCXX_USE_ALLOC_PTR_FOR_RB_TREE=9001
will force std::_Rb_tree to always use the new node types. This macro is
currently undocumented, which needs to be fixed.
As _Rb_tree is using _Base_ptr to represent the tree this change also
simplifies the implementation by removing all the const pointer types
and associated methods.
libstdc++-v3/ChangeLog:
PR libstdc++/57272
* include/bits/stl_tree.h
[_GLIBCXX_USE_ALLOC_PTR_FOR_RB_TREE]: New macro to control usage of the
code required to support fancy allocator pointer type.
(_Rb_tree_node_base::_Const_Base_ptr): Remove.
(_Rb_tree_node_base::_S_minimum, _Rb_tree_node_base::_S_maximum): Remove
overloads for _Const_Base_ptr.
(_Rb_tree_node_base::_M_base_ptr()): New.
(_Rb_tree_node::_Link_type): Remove.
(_Rb_tree_node::_M_node_ptr()): New.
(__rb_tree::_Node_base<>): New.
(__rb_tree::_Header<>): New.
(__rb_tree::_Node<>): New.
(_Rb_tree_increment(const _Rb_tree_node_base*)): Remove declaration.
(_Rb_tree_decrement(const _Rb_tree_node_base*)): Remove declaration.
(_Rb_tree_iterator<>::_Self): Remove.
(_Rb_tree_iterator<>::_Link_type): Rename into...
(_Rb_tree_iterator<>::_Node_ptr): ...this.
(_Rb_tree_const_iterator<>::_Link_type): Rename into...
(_Rb_tree_const_iterator<>::_Node_ptr): ...this.
(_Rb_tree_const_iterator<>::_M_const_cast): Remove.
(_Rb_tree_const_iterator<>::_M_node): Change type into _Base_ptr.
(__rb_tree::_Iterator<>): New.
(__rb_tree::_Node_traits<>): New.
(_Rb_tree<>::_Node_base, _Rb_tree::_Node): New.
(_Rb_tree<>::_Link_type): Rename into...
(_Rb_tree<>::_Node_ptr): ...this.
(_Rb_tree<>::_Const_Base_ptr, _Rb_tree<>::_Const_Node_ptr): Remove.
(_Rb_tree<>::_M_mbegin): Remove.
(_Rb_tree<>::_M_begin_node()): New.
(_S_key(const _Node&)): New.
(_S_key(_Base_ptr)): New, call latter.
(_S_key(_Node_ptr)): Likewise.
(_Rb_tree<>::_S_left(_Const_Base_ptr)): Remove.
(_Rb_tree<>::_S_right(_Const_Base_ptr)): Remove.
(_Rb_tree<>::_S_maximum(_Const_Base_ptr)): Remove.
(_Rb_tree<>::_S_minimum(_Const_Base_ptr)): Remove.
* testsuite/23_containers/map/allocator/ext_ptr.cc: New test case.
* testsuite/23_containers/multimap/allocator/ext_ptr.cc: New test case.
* testsuite/23_containers/multiset/allocator/ext_ptr.cc: New test case.
* testsuite/23_containers/set/allocator/ext_ptr.cc: New test case.
* testsuite/23_containers/set/requirements/explicit_instantiation/alloc_ptr.cc:
New test case.
* testsuite/23_containers/set/requirements/explicit_instantiation/alloc_ptr_ignored.cc:
New test case.
|
|
This implements the C++23 container adaptors std::flat_set and
std::flat_multiset from P1222R4. The implementation is essentially
an simpler and pared down version of std::flat_map.
libstdc++-v3/ChangeLog:
* include/Makefile.am: Add new header <flat_set>.
* include/Makefile.in: Regenerate.
* include/bits/version.def (__cpp_flat_set): Define.
* include/bits/version.h: Regenerate
* include/precompiled/stdc++.h: Include <flat_set>.
* include/std/flat_set: New file.
* src/c++23/std.cc.in: Export <flat_set>.
* testsuite/23_containers/flat_multiset/1.cc: New test.
* testsuite/23_containers/flat_set/1.cc: New test.
Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
|
|
This implements the C++23 container adaptors std::flat_map and
std::flat_multimap from P0429R9. The implementation is shared
as much as possible between the two adaptors via a common base
class that's parameterized according to key uniqueness.
libstdc++-v3/ChangeLog:
* include/Makefile.am: Add new header <flat_map>.
* include/Makefile.in: Regenerate.
* include/bits/alloc_traits.h (__not_allocator_like): New concept.
* include/bits/stl_function.h (__transparent_comparator): Likewise.
* include/bits/stl_iterator_base_types.h (__has_input_iter_cat):
Likewise.
* include/bits/uses_allocator.h (__allocator_for): Likewise.
* include/bits/utility.h (sorted_unique_t): Define for C++23.
(sorted_unique): Likewise.
(sorted_equivalent_t): Likewise.
(sorted_equivalent): Likewise.
* include/bits/version.def (flat_map): Define.
* include/bits/version.h: Regenerate.
* include/precompiled/stdc++.h: Include <flat_map>.
* include/std/flat_map: New file.
* src/c++23/std.cc.in: Export <flat_map>.
* testsuite/23_containers/flat_map/1.cc: New test.
* testsuite/23_containers/flat_multimap/1.cc: New test.
Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
|
|
libstdc++-v3/ChangeLog:
* include/bits/ranges_base.h (__detail::__range_key_type):
Define as per P1206R7.
(__detail::__range_mapped_type): Likewise.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
|
|
|
|
Rather than calling std::__addressof in std::addressof we can directly
call __builtin_addressof to bypass 1 function call.
libstdc++-v3/ChangeLog:
* include/bits/move.h (std::addressof): Call __builtin_addressof.
|
|
We are currently generating a loop which has more comparisons than you'd
typically need as the probablities on the small size loop are such that it
assumes the likely case is that an element is not found.
This again generates a pattern that's harder for branch predictors to follow,
but also just generates more instructions for the what one could say is the
typical case: That your hashtable contains the entry you are looking for.
This patch adds a __builtin_expect in _M_find_before_node where at the moment
the loop is optimized for the case where we don't do any iterations.
A simple testcase is (compiled with -fno-split-path to simulate the loop
in libstdc++):
#include <stdbool.h>
bool foo (int **a, int n, int val, int *tkn)
{
for (int i = 0; i < n; i++)
{
if (!a[i] || a[i]==tkn)
return false;
if (*a[i] == val)
return true;
}
}
which generataes:
foo:
cmp w1, 0
ble .L1
add x1, x0, w1, uxtw 3
b .L4
.L9:
ldr w4, [x4]
cmp w4, w2
beq .L6
cmp x0, x1
beq .L1
.L4:
ldr x4, [x0]
add x0, x0, 8
cmp x4, 0
ccmp x4, x3, 4, ne
bne .L9
mov w0, 0
.L1:
ret
.L6:
mov w0, 1
ret
i.e. BB rotation makes is generate an unconditional branch to a conditional
branch. However this method is only called when the size is above a certain
threshold, and so it's likely that we have to do that first iteration.
Adding:
#include <stdbool.h>
bool foo (int **a, int n, int val, int *tkn)
{
for (int i = 0; i < n; i++)
{
if (__builtin_expect(!a[i] || a[i]==tkn, 0))
return false;
if (*a[i] == val)
return true;
}
}
to indicate that we will likely do an iteration more generates:
foo:
cmp w1, 0
ble .L1
add x1, x0, w1, uxtw 3
.L4:
ldr x4, [x0]
add x0, x0, 8
cmp x4, 0
ccmp x4, x3, 4, ne
beq .L5
ldr w4, [x4]
cmp w4, w2
beq .L6
cmp x0, x1
bne .L4
.L1:
ret
.L5:
mov w0, 0
ret
.L6:
mov w0, 1
ret
which results in ~0-10% extra on top of the previous patch.
In table form:
+-------------+---------------+-------+--------------------+-------------------+-----------------+
| benchmark | Type | Size | Inline vs baseline | final vs baseline | final vs inline |
+-------------+---------------+-------+--------------------+-------------------+-----------------+
| find many | uint64_t | 11253 | -15.67% | -22.96% | -8.65% |
| find many | uint64_t | 11253 | -16.74% | -23.37% | -7.96% |
| find single | uint64_t | 345 | -5.88% | -11.54% | -6.02% |
| find many | string | 11253 | -4.50% | -9.56% | -5.29% |
| find single | uint64_t | 345 | -4.38% | -9.41% | -5.26% |
| find single | shared string | 11253 | -6.67% | -11.00% | -4.64% |
| find single | shared string | 11253 | -4.63% | -9.03% | -4.61% |
| find single | shared string | 345 | -10.41% | -14.44% | -4.50% |
| find many | string | 11253 | -3.41% | -7.51% | -4.24% |
| find many | shared string | 11253 | -2.30% | -5.72% | -3.50% |
| find many | string | 13 | 2.86% | -0.30% | -3.07% |
| find single | string | 11253 | 4.47% | 1.34% | -3.00% |
| find many | custom string | 11253 | 0.25% | -2.75% | -2.99% |
| find single | uint64_t | 345 | 2.99% | 0.01% | -2.90% |
| find single | shared string | 345 | -11.53% | -13.67% | -2.41% |
| find single | uint64_t | 11253 | 0.49% | -1.59% | -2.07% |
+-------------+---------------+-------+--------------------+-------------------+-----------------+
libstdc++-v3/ChangeLog:
* include/bits/hashtable.h
(_M_find_before_node): Make it likely that the map has at least one
entry and so we do at least one iteration.
|
|
We don't know what state an arbitrary sequence container will be in
after moving from it, so a moved-from std::priority_queue needs to clear
the moved-from container to ensure it doesn't contain elements that are
in an invalid order for the queue. An alternative would be to call
std::make_heap again to re-establish the rvalue queue's invariant, but
that could potentially cause an exception to be thrown. Just clearing it
so the sequence is empty seems safer and more likely to match user
expectations.
libstdc++-v3/ChangeLog:
PR libstdc++/118088
* include/bits/stl_queue.h (priority_queue(priority_queue&&)):
Clear the source object after moving from it.
(priority_queue(priority_queue&&, const Alloc&)): Likewise.
(operator=(priority_queue&&)): Likewise.
* testsuite/23_containers/priority_queue/118088.cc: New test.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
|
|
In GCC 12 there was a ~40% regression in the performance of hashmap->find.
This regression came about accidentally:
Before GCC 12 the find function was small enough that IPA would inline it even
though it wasn't marked inline. In GCC-12 an optimization was added to perform
a linear search when the entries in the hashmap are small.
This increased the size of the function enough that IPA would no longer inline.
Inlining had two benefits:
1. The return value is a reference. so it has to be returned and dereferenced
even though the search loop may have already dereference it.
2. The pattern is a hard pattern to track for branch predictors. This causes
a large number of branch misses if the value is immediately checked and
branched on. i.e. if (a != m.end()) which is a common pattern.
The patch fixes both these issues by adding the inline keyword to _M_locate
to allow the inliner to consider inlining again.
This and the other patches have been ran through serveral benchmarks where
the size, number of elements searched for and type (reference vs value) etc
were tested.
The change shows no statistical regression, but an average find improvement of
~27% and a range between ~10-60% improvements. A selection of the results:
+-----------+--------------------+-------+----------+
| Group | Benchmark | Size | % Inline |
+-----------+--------------------+-------+----------+
| Find | unord<uint64_t | 11274 | 53.52% |
| Find | unord<uint64_t | 11254 | 47.98% |
| Find Mult | unord<uint64_t | 12 | 47.62% |
| Find Mult | unord<std::string | 12 | 44.94% |
| Find Mult | unord<std::string | 10 | 44.89% |
| Find Mult | unord<uint64_t | 11 | 40.90% |
| Find Mult | unord<uint64_t | 352 | 30.57% |
| Find | unord<uint64_t | 351 | 28.27% |
| Find Mult | unord<uint64_t | 342 | 26.80% |
| Find | unord<std::string | 12 | 25.66% |
| Find Mult | unord<std::string | 352 | 23.12% |
| Find | unord<std::string | 13 | 20.36% |
| Find Mult | unord<std::string | 355 | 19.23% |
| Find | unord<std::string | 353 | 18.59% |
| Find | unord<uint64_t | 350 | 15.43% |
| Find | unord<std::string | 11260 | 11.80% |
| Find | unord<std::string | 352 | 11.12% |
| Find | unord<std::string | 11262 | 9.97% |
+-----------+--------------------+-------+----------+
libstdc++-v3/ChangeLog:
* include/bits/hashtable.h: Inline _M_locate.
|
|
The mapping from char to wchar_t needs to handle 'i' and 'I' but those
were absent from the table that is used for some non-ASCII encodings.
libstdc++-v3/ChangeLog:
* include/bits/basic_string.h (__to_wstring_numeric): Add 'i'
and 'I' to mapping.
|
|
This is both a performance optimization and a partial fix for PR 98723.
This commit fixes the issue for bracket expressions that do not depend
on the locale's collation facet. Examples:
* Character ranges ([a-z]) when std::regex::collate is not set
* Character classes ([:alnum:])
* Individual characters ([abc])
Signed-off-by: Luca Bacci <luca.bacci982@gmail.com>
libstdc++-v3/ChangeLog:
PR libstdc++/98723
* include/bits/regex_compiler.tcc (_BracketMatcher::_M_apply):
Only use transform_primary when an equivalence set is used.
|
|
|
|
libstdc++-v3/ChangeLog:
* include/debug/safe_local_iterator.h (_GLIBCXX_DEBUG_VERIFY_OPERANDS):
Add parentheses to avoid -Wparentheses warning.
|
|
[PR118035]
Inserting an empty range into a std::deque results in undefined calls to
either std::copy, std::copy_backward, std::move, or std::move_backward.
We call those algos with invalid arguments where the output range is the
same as the input range, e.g. std::copy(first, last, first) which
violates the preconditions for the algorithms.
This fix simply returns early if there's nothing to insert. Most callers
already ensure that we don't even call _M_range_insert_aux with an empty
range, but some callers don't. Rather than checking for n == 0 in each
of the callers, this just does the check once and uses __builtin_expect
to treat empty insertions as unlikely.
libstdc++-v3/ChangeLog:
PR libstdc++/118035
* include/bits/deque.tcc (_M_range_insert_aux): Return
immediately if inserting an empty range.
* testsuite/23_containers/deque/modifiers/insert/118035.cc: New
test.
|
|
|
|
Currently the _M_bucket members are left uninitialized for
default-initialized local iterators, and then copy construction copies
indeterminate values. We should just ensure they're initialized on
construction.
Setting them to zero makes default-initialization consistent with
value-initialization and avoids indeterminate values.
For the _Local_iterator_base<..., false> specialization we preserve the
existing behaviour of setting _M_bucket_count to -1 in the default
constructor, as a sentinel value to indicate there's no hash object
present.
libstdc++-v3/ChangeLog:
* include/bits/hashtable_policy.h (_Local_iterator_base): Use
default member-initializers.
|