Tested x86_64-linux. -- >8 --
We implement std::copy, std::fill etc. as a series of calls to other overloads which incrementally peel off layers of iterator wrappers. This adds a high abstraction penalty for -O0 and potentially even -O1. Add the always_inline attribute to several functions that are just a single return statement (and maybe a static_assert, or some concept-checking assertions which are disabled by default). libstdc++-v3/ChangeLog: * include/bits/stl_algobase.h (__copy_move_a1, __copy_move_a) (__copy_move_backward_a1, __copy_move_backward_a, move_backward) (__fill_a1, __fill_a, fill, __fill_n_a, fill_n, __equal_aux): Add always_inline attribute to one-line forwarding functions. --- libstdc++-v3/include/bits/stl_algobase.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index d9d1d00b113..b2f5b96d46e 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -500,12 +500,14 @@ _GLIBCXX_END_NAMESPACE_CONTAINER __copy_move_a1(_II, _II, _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>); template<bool _IsMove, typename _II, typename _OI> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline _OI __copy_move_a1(_II __first, _II __last, _OI __result) { return std::__copy_move_a2<_IsMove>(__first, __last, __result); } template<bool _IsMove, typename _II, typename _OI> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline _OI __copy_move_a(_II __first, _II __last, _OI __result) @@ -757,6 +759,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER #undef _GLIBCXX_ADVANCE template<bool _IsMove, typename _BI1, typename _BI2> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline _BI2 __copy_move_backward_a1(_BI1 __first, _BI1 __last, _BI2 __result) @@ -785,6 +788,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>); template<bool _IsMove, typename _II, typename _OI> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline _OI __copy_move_backward_a(_II __first, _II __last, _OI __result) @@ -840,6 +844,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER * that the start of the output range may overlap [first,last). */ template<typename _BI1, typename _BI2> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) @@ -875,6 +880,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER * that the start of the output range may overlap [first,last). */ template<typename _BI1, typename _BI2> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline _BI2 move_backward(_BI1 __first, _BI1 __last, _BI2 __result) @@ -958,6 +964,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER } template<typename _Ite, typename _Cont, typename _Tp> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline void __fill_a1(::__gnu_cxx::__normal_iterator<_Ite, _Cont> __first, @@ -977,6 +984,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER const bool&); template<typename _FIte, typename _Tp> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline void __fill_a(_FIte __first, _FIte __last, const _Tp& __value) @@ -1002,6 +1010,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER * to @c memset or @c wmemset. */ template<typename _ForwardIterator, typename _Tp> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline void fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) @@ -1108,6 +1117,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER std::input_iterator_tag); template<typename _OutputIterator, typename _Size, typename _Tp> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline _OutputIterator __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value, @@ -1120,6 +1130,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER } template<typename _OutputIterator, typename _Size, typename _Tp> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline _OutputIterator __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value, @@ -1132,6 +1143,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER } template<typename _OutputIterator, typename _Size, typename _Tp> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline _OutputIterator __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value, @@ -1167,6 +1179,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER // DR 865. More algorithms that throw away information // DR 426. search_n(), fill_n(), and generate_n() with negative n template<typename _OI, typename _Size, typename _Tp> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline _OI fill_n(_OI __first, _Size __n, const _Tp& __value) @@ -1246,6 +1259,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER } template<typename _II1, typename _II2> + __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR inline bool __equal_aux(_II1 __first1, _II1 __last1, _II2 __first2) -- 2.46.2