Skip to content

Commit 50910bf

Browse files
committedMar 23, 2017
[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 llvm-svn: 298601
1 parent c53e96c commit 50910bf

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed
 

Diff for: ‎libcxx/include/vector

+4-2
Original file line numberDiff line numberDiff line change
@@ -413,8 +413,10 @@ inline _LIBCPP_INLINE_VISIBILITY
413413
void
414414
__vector_base<_Tp, _Allocator>::__destruct_at_end(pointer __new_last) _NOEXCEPT
415415
{
416-
while (__new_last != __end_)
417-
__alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__end_));
416+
pointer __soon_to_be_end = __end_;
417+
while (__new_last != __soon_to_be_end)
418+
__alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__soon_to_be_end));
419+
__end_ = __new_last;
418420
}
419421

420422
template <class _Tp, class _Allocator>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is dual licensed under the MIT and the University of Illinois Open
6+
// Source Licenses. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
// <vector>
11+
12+
// void clear();
13+
14+
#include <vector>
15+
#include <cassert>
16+
17+
#include "min_allocator.h"
18+
#include "asan_testing.h"
19+
20+
int main()
21+
{
22+
{
23+
int a[] = {1, 2, 3};
24+
std::vector<int> c(a, a+3);
25+
c.clear();
26+
assert(c.empty());
27+
LIBCPP_ASSERT(c.__invariants());
28+
LIBCPP_ASSERT(is_contiguous_container_asan_correct(c));
29+
}
30+
#if TEST_STD_VER >= 11
31+
{
32+
int a[] = {1, 2, 3};
33+
std::vector<int, min_allocator<int>> c(a, a+3);
34+
c.clear();
35+
assert(c.empty());
36+
LIBCPP_ASSERT(c.__invariants());
37+
LIBCPP_ASSERT(is_contiguous_container_asan_correct(c));
38+
}
39+
#endif
40+
}

0 commit comments

Comments
 (0)
Please sign in to comment.