Auto merge of #123930 - Mark-Simulacrum:vec-length-invariant, r=jhpratt
Tell LLVM Vec::len is invariant across growth This allows LLVM to avoid re-loading it from memory.
This commit is contained in:
commit
13eb8c736c
@ -1991,15 +1991,17 @@ fn drop(&mut self) {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_confusables("push_back", "put", "append")]
|
||||
pub fn push(&mut self, value: T) {
|
||||
// Inform codegen that the length does not change across grow_one().
|
||||
let len = self.len;
|
||||
// This will panic or abort if we would allocate > isize::MAX bytes
|
||||
// or if the length increment would overflow for zero-sized types.
|
||||
if self.len == self.buf.capacity() {
|
||||
if len == self.buf.capacity() {
|
||||
self.buf.grow_one();
|
||||
}
|
||||
unsafe {
|
||||
let end = self.as_mut_ptr().add(self.len);
|
||||
let end = self.as_mut_ptr().add(len);
|
||||
ptr::write(end, value);
|
||||
self.len += 1;
|
||||
self.len = len + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
16
tests/codegen/vec-len-invariant.rs
Normal file
16
tests/codegen/vec-len-invariant.rs
Normal file
@ -0,0 +1,16 @@
|
||||
//@ compile-flags: -O
|
||||
//@ only-64bit
|
||||
//
|
||||
// This test confirms that we do not reload the length of a Vec after growing it in push.
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// CHECK-LABEL: @should_load_once
|
||||
#[no_mangle]
|
||||
pub fn should_load_once(v: &mut Vec<u8>) {
|
||||
// CHECK: load i64
|
||||
// CHECK: call {{.*}}grow_one
|
||||
// CHECK-NOT: load i64
|
||||
// CHECK: add {{.*}}, 1
|
||||
v.push(1);
|
||||
}
|
Loading…
Reference in New Issue
Block a user