Hi, This patch makes it clear that vector sizes and capacities are not negative. With recent change to ipa-fnsummary this should not affect inlining and improves codegen of some vector manipulation functions.
I tested clang build. Looking for throw_bad calls there are only 3 called considerably often (bad_allloc, bad_array_new_length and function_callv). The patch seems to reduce bad_alloc and bad_array_new_length calls considerably: bad_alloc 380->147 bad_array_new_length 832->128 Bootstrapped/regtested x86_64-linux and approved by Jonathan. libstdc++-v3/ChangeLog: PR tree-optimization/109442 * include/bits/stl_vector.h: (vector::size(), vector::capacity()): Add __builtin_unreachable call to announce that size and capacity are non-negative. gcc/testsuite/ChangeLog: PR tree-optimization/109442 * g++.dg/tree-ssa/pr109442.C: New test. diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr109442.C b/gcc/testsuite/g++.dg/tree-ssa/pr109442.C new file mode 100644 index 00000000000..ec40c470c8d --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr109442.C @@ -0,0 +1,12 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-O1 -fdump-tree-optimized" } +#include <vector> +#define T int +T vat1(std::vector<T> v1) { + auto v = v1; + return 10; +} +// This should compile to empty function; check that no size of +// vector is determined and there is no allocation +// { dg-final { scan-tree-dump-not "_M_start" "optimized" } } +// { dg-final { scan-tree-dump-not "delete" "optimized" } } diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index df48ba3377f..3ece16b2fac 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -1114,7 +1114,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR size_type size() const _GLIBCXX_NOEXCEPT - { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); } + { + ptrdiff_t __dif = this->_M_impl._M_finish - this->_M_impl._M_start; + if (__dif < 0) + __builtin_unreachable (); + return size_type(__dif); + } /** Returns the size() of the largest possible %vector. */ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR @@ -1201,8 +1206,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER size_type capacity() const _GLIBCXX_NOEXCEPT { - return size_type(this->_M_impl._M_end_of_storage - - this->_M_impl._M_start); + ptrdiff_t __dif = this->_M_impl._M_end_of_storage + - this->_M_impl._M_start; + if (__dif < 0) + __builtin_unreachable (); + return size_type(__dif); } /**