Closed
Description
I'm not quite sure if this has a performance impact, but I noticed that rust seems to be generating different code for moves inside a function and a function argument. Here's an example:
struct Foo {
x: Vec<int>,
}
#[inline(never)]
#[no_mangle]
fn interior(x: Vec<int>) -> Vec<int> {
let Foo { x } = Foo { x: x };
x
}
#[inline(never)]
#[no_mangle]
fn exterior(x: Vec<int>) -> Vec<int> {
x
}
fn main() {
let x = interior(Vec::new());
println!("{}", x);
let x = exterior(Vec::new());
println!("{}", x);
}
At opt-level=3, llvm generates:
; Function Attrs: noinline uwtable
define internal fastcc void @interior(%"struct.collections::vec::Vec<[int]>[#6]"* noalias nocapture nonnull sret, %"struct.collections::vec::Vec<[int]>[#6]"* noalias nocapture nonnull) unnamed_addr #0 {
"_ZN32collections..vec..Vec$LT$int$GT$39glue_drop.$x22glue_drop$x22$LP$1381$RP$17h0c4580be04eb3673E.exit4":
%2 = bitcast %"struct.collections::vec::Vec<[int]>[#6]"* %1 to i8*
%3 = bitcast %"struct.collections::vec::Vec<[int]>[#6]"* %1 to <2 x i64>*
%4 = load <2 x i64>* %3, align 8
%.sroa.7.0..sroa_idx20 = getelementptr inbounds %"struct.collections::vec::Vec<[int]>[#6]"* %1, i64 0, i32 2
%.sroa.7.0.copyload = load i64** %.sroa.7.0..sroa_idx20, align 8
%5 = bitcast %"struct.collections::vec::Vec<[int]>[#6]"* %0 to <2 x i64>*
store <2 x i64> %4, <2 x i64>* %5, align 8
%x.sroa.6.0..sroa_idx13 = getelementptr inbounds %"struct.collections::vec::Vec<[int]>[#6]"* %0, i64 0, i32 2
store i64* %.sroa.7.0.copyload, i64** %x.sroa.6.0..sroa_idx13, align 8
tail call void @llvm.lifetime.end(i64 24, i8* %2)
ret void
}
...
; Function Attrs: noinline uwtable
define internal fastcc void @exterior(%"struct.collections::vec::Vec<[int]>[#6]"* noalias nocapture nonnull sret, %"struct.collections::vec::Vec<[int]>[#6]"* noalias nocapture nonnull) unnamed_addr #0 {
"_ZN32collections..vec..Vec$LT$int$GT$39glue_drop.$x22glue_drop$x22$LP$1381$RP$17h0c4580be04eb3673E.exit":
%2 = bitcast %"struct.collections::vec::Vec<[int]>[#6]"* %1 to i8*
%3 = bitcast %"struct.collections::vec::Vec<[int]>[#6]"* %0 to i8*
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %2, i64 24, i32 8, i1 false)
tail call void @llvm.lifetime.end(i64 24, i8* %2)
ret void
}
cc: @pcwalton.