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);
}
/**