Author: brucem Date: Thu Mar 23 09:39:23 2017 New Revision: 298601 URL: http://llvm.org/viewvc/llvm-project?rev=298601&view=rev Log: [libcxx] Improve code generation for vector::clear().
Summary: By manipulating a local variable in the loop, when the loop can be optimized away (due to no non-trivial destructors), this lets it be fully optimized away and we modify the __end_ separately. This results in a substantial improvement in the generated code. Prior to this change, this would be generated (on x86_64): movq (%rdi), %rdx movq 8(%rdi), %rcx cmpq %rdx, %rcx je LBB2_2 leaq -12(%rcx), %rax subq %rdx, %rax movabsq $-6148914691236517205, %rdx ## imm = 0xAAAAAAAAAAAAAAAB mulq %rdx shrq $3, %rdx notq %rdx leaq (%rdx,%rdx,2), %rax leaq (%rcx,%rax,4), %rax movq %rax, 8(%rdi) And after: movq (%rdi), %rax movq %rax, 8(%rdi) This brings this in line with what other implementations do. Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D25241 Added: libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/clear.pass.cpp Modified: libcxx/trunk/include/vector Modified: libcxx/trunk/include/vector URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/vector?rev=298601&r1=298600&r2=298601&view=diff ============================================================================== --- libcxx/trunk/include/vector (original) +++ libcxx/trunk/include/vector Thu Mar 23 09:39:23 2017 @@ -413,8 +413,10 @@ inline _LIBCPP_INLINE_VISIBILITY void __vector_base<_Tp, _Allocator>::__destruct_at_end(pointer __new_last) _NOEXCEPT { - while (__new_last != __end_) - __alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__end_)); + pointer __soon_to_be_end = __end_; + while (__new_last != __soon_to_be_end) + __alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__soon_to_be_end)); + __end_ = __new_last; } template <class _Tp, class _Allocator> Added: libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/clear.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/clear.pass.cpp?rev=298601&view=auto ============================================================================== --- libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/clear.pass.cpp (added) +++ libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/clear.pass.cpp Thu Mar 23 09:39:23 2017 @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <vector> + +// void clear(); + +#include <vector> +#include <cassert> + +#include "min_allocator.h" +#include "asan_testing.h" + +int main() +{ + { + int a[] = {1, 2, 3}; + std::vector<int> c(a, a+3); + c.clear(); + assert(c.empty()); + LIBCPP_ASSERT(c.__invariants()); + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); + } +#if TEST_STD_VER >= 11 + { + int a[] = {1, 2, 3}; + std::vector<int, min_allocator<int>> c(a, a+3); + c.clear(); + assert(c.empty()); + LIBCPP_ASSERT(c.__invariants()); + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); + } +#endif +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits