Rb_tree constructor optimization
François Dumont
frs.dumont@gmail.com
Tue May 15 05:31:00 GMT 2018
On 11/05/2018 14:16, Jonathan Wakely wrote:
> On 06/05/18 16:06 +0200, François Dumont wrote:
>> Here is the rework of this patch.
>>
>>
>> On 02/05/2018 13:49, Jonathan Wakely wrote:
>>> There's no changelog entry with the patch, so to recap, the changes
>>> are:
>>>
>>> - noexcept specifications are automatically deduced instead of being
>>> Â stated explicitly.
>>
>> I simplified this part, it is not deduced anymore except for Debug
>> mode relying on Normal mode qualifications.
>>
>>>
>>> - The allocator-extended move constructors get correct exception
>>> Â specifications in Debug Mode (consistent with normal mode). This
>>> Â should be done anyway, independent of any other changes.
>> I kept this untouch.
>>>
>>> - We avoid a `if (__x._M_root() != nullptr)` branch in the case where
>>> Â the allocator-extended move constructor is used with an always-equal
>>> Â allocator, right?
>> Kept too.
>>>
>>> Compilation time for containers is already **much** slower since the
>>> allocator-extended constructors were added for GCC 5.x, despite very
>>> few people ever using those constructors. This patch seems to require
>>> even more work from the compiler to parse constructors nobody uses.
>> I restore direct qualifications.
>>
>>> diff --git a/libstdc++-v3/include/bits/stl_map.h
>>> b/libstdc++-v3/include/bits/stl_map.h
>>>> index a4a026e..2b8fd27 100644
>>>> --- a/libstdc++-v3/include/bits/stl_map.h
>>>> +++ b/libstdc++-v3/include/bits/stl_map.h
>>>> @@ -240,8 +240,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>>>>
>>>> Â Â Â Â Â /// Allocator-extended move constructor.
>>>> Â Â Â Â Â map(map&& __m, const allocator_type& __a)
>>>> - noexcept(is_nothrow_copy_constructible<_Compare>::value
>>>> -Â Â Â Â Â Â Â Â Â Â && _Alloc_traits::_S_always_equal())
>>>> +Â Â Â Â Â noexcept( noexcept(
>>>> +Â Â Â _Rep_type(std::move(__m._M_t), declval<_Pair_alloc_type>())) )
>>>
>>> All these calls to declval need to be qualified to avoid ADL.
>>>
>>> It seems strange to have a mix of real values and declval expressions,
>>> rather than:
>>>
>>> Â Â Â Â _Rep_type(std::declval<_Rep_type>(),
>>> std::declval<_Pair_alloc_type>())) )
>> I add std:: qualitification and generalized usage.
>>>
>>>>
>>>> -Â Â Â Â Â _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a);
>>>> +Â Â Â private:
>>>> +Â Â Â Â Â _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a, true_type)
>>>> +
>>>> noexcept(is_nothrow_move_constructible<_Rb_tree_impl<_Compare>>::value)
>>>
>>> This is wrong.
>>
>> As stated previously I removed this but based on this remark I also
>> change the _Rb_tree_impl() qualification so that it doesn't depend
>> anymore on allocator default constructor qualification.
>>
>> I've added a test for that too.
>>> This can use std::is_nothrow_constructible
>>>
>> Indeed.
>>>> +Â Â Â Â Â Â Â Â Â Â "noexcept move constructor with allocator" );
>>>> +
>>>> +struct ExceptLess
>>>
>>> Please name this "ThrowingLess" instead of "ExceptLess", I think
>>> that's more descriptive.
>> I prefered "not_noexcept" prefix cause those operators are not
>> throwing anything neither.
>>
>> Tested under Linux x86_64, ok to commit ?
>>
>> Â Â Â * include/bits/stl_tree.h
>> Â Â Â (_Rb_tree_impl()):
>> Â Â Â Remove is_nothrow_default_constructible<_Node_allocator> from
>> noexcept
>> Â Â Â qualification.
>> Â Â Â (_Rb_tree_impl(_Rb_tree_impl&&, _Node_allocator&&)): New.
>> Â Â Â (_Rb_tree(_Rb_tree&&, _Node_allocator&&, std::true_type)): New,
>> use latter.
>> Â Â Â (_Rb_tree(_Rb_tree&&, _Node_allocator&&, std::false_type)): New.
>> Â Â Â (_Rb_tree(_Rb_tree&&, _Node_allocator&&)): Adapt, use latters.
>> Â Â Â * include/debug/map.h
>> Â Â Â (map(map&&, const_allocator_type&)): Add noexcept qualitication.
>> Â Â Â * include/debug/multimap.h
>> Â Â Â (multimap(multimap&&, const_allocator_type&)): Add noexcept
>> qualification.
>> Â Â Â * include/debug/set.h
>> Â Â Â (set(set&&, const_allocator_type&)): Add noexcept qualitication.
>> Â Â Â * include/debug/multiset.h
>> Â Â Â (multiset(multiset&&, const_allocator_type&)): Add noexcept
>> qualification.
>> Â Â Â * testsuite/23_containers/map/cons/noexcept_default_construct.cc:
>> Â Â Â Add checks.
>> Â Â Â * testsuite/23_containers/map/cons/noexcept_move_construct.cc:
>> Â Â Â Add checks.
>> Â Â Â *
>> testsuite/23_containers/multimap/cons/noexcept_default_construct.cc:
>> Â Â Â Add checks.
>> Â Â Â * testsuite/23_containers/multimap/cons/noexcept_move_construct.cc:
>> Â Â Â Add checks.
>> Â Â Â *
>> testsuite/23_containers/multiset/cons/noexcept_default_construct.cc:
>> Â Â Â Add checks.
>> Â Â Â * testsuite/23_containers/multiset/cons/noexcept_move_construct.cc:
>> Â Â Â Add checks.
>> Â Â Â * testsuite/23_containers/set/cons/noexcept_default_construct.cc:
>> Â Â Â Add checks.
>> Â Â Â * testsuite/23_containers/set/cons/noexcept_move_construct.cc:
>> Â Â Â Add checks.
>>
>> François
>>
>
>> diff --git a/libstdc++-v3/include/bits/stl_tree.h
>> b/libstdc++-v3/include/bits/stl_tree.h
>> index d0a8448..9e59259 100644
>> --- a/libstdc++-v3/include/bits/stl_tree.h
>> +++ b/libstdc++-v3/include/bits/stl_tree.h
>> @@ -698,8 +698,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>
>> Â Â Â Â Â _Rb_tree_impl()
>> Â Â Â Â Â Â Â Â Â Â _GLIBCXX_NOEXCEPT_IF(
>> - is_nothrow_default_constructible<_Node_allocator>::value
>> -Â Â Â Â Â Â Â && is_nothrow_default_constructible<_Base_key_compare>::value )
>> +Â Â Â Â Â Â Â // is_nothrow_default_constructible<_Node_allocator>::value &&
>> + is_nothrow_default_constructible<_Base_key_compare>::value )
>> Â Â Â Â Â : _Node_allocator()
>> Â Â Â Â Â { }
>
> This part wasn't in the previous patch and seems wrong:
> https://cplusplus.github.io/LWG/issue2455
>
Yes, I must have been tired when I decided to do such a thing.
Here it is again even more simplified. Should I backport the Debug mode
fix to 8 branch ?
   * include/bits/stl_tree.h
   (_Rb_tree_impl(_Rb_tree_impl&&, _Node_allocator&&)): New.
   (_Rb_tree(_Rb_tree&&, _Node_allocator&&, true_type)): New, use latter.
   (_Rb_tree(_Rb_tree&&, _Node_allocator&&, false_type)): New.
   (_Rb_tree(_Rb_tree&&, _Node_allocator&&)): Adapt, use latters.
   * include/debug/map.h
   (map(map&&, const_allocator_type&)): Add noexcept qualitication.
   * include/debug/multimap.h
   (multimap(multimap&&, const_allocator_type&)): Add noexcept
qualification.
   * include/debug/set.h
   (set(set&&, const_allocator_type&)): Add noexcept qualitication.
   * include/debug/multiset.h
   (multiset(multiset&&, const_allocator_type&)): Add noexcept
qualification.
   * testsuite/23_containers/map/cons/noexcept_default_construct.cc:
   Add checks.
   * testsuite/23_containers/map/cons/noexcept_move_construct.cc:
   Add checks.
   * testsuite/23_containers/multimap/cons/noexcept_default_construct.cc:
   Add checks.
   * testsuite/23_containers/multimap/cons/noexcept_move_construct.cc:
   Add checks.
   * testsuite/23_containers/multiset/cons/noexcept_default_construct.cc:
   Add checks.
   * testsuite/23_containers/multiset/cons/noexcept_move_construct.cc:
   Add checks.
   * testsuite/23_containers/set/cons/noexcept_default_construct.cc:
   Add checks.
   * testsuite/23_containers/set/cons/noexcept_move_construct.cc:
   Add checks.
Ok to commit ?
François
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rb_tree.patch
Type: text/x-patch
Size: 14488 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20180515/a9ea78b9/attachment.bin>
More information about the Libstdc++
mailing list