Reputation: 2159
If I assign a variable (with a type without copy semantics) to a second one, rustc creates a copy of the value even if the first one cannot be used/accessed anymore.
For example:
#[derive(Debug)]
struct T {
val: i32,
}
fn main() {
let v1 = T { val: 123 };
let v2 = v1;
// println!("{:?}", v1); error!
println!("{:?}", v2);
}
This generates LLVM IR which contains two store operations:
%v2 = alloca i32, align 4
%v1 = alloca i32, align 4
store i32 123, i32* %v1, align 4
store i32 123, i32* %v2, align 4
Isn't it unnecessary workload to copy values with move semantics if the first copy cannot be used anymore?
Upvotes: 0
Views: 272
Reputation: 14915
LLVM was specifically designed to perform optimizations. A front-end will try to encode everything it knows about the operations being performed in the LLVM IR and then invoke optimizations upon the LLVM IR.
If you turn on optimizations you'll indeed only get:
%v2 = alloca i32, align 4
%0 = bitcast i32* %v2 to i8*, !dbg !36
call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0), !dbg !36
store i32 123, i32* %v2, align 4, !dbg !37
%v1
has been optimized away entirely.
https://godbolt.org/z/fW9457eEn
Upvotes: 2
Reputation: 23586
Because copy vs move is language semantics not how it is done in the generated code. Rust always (maybe that have changed?) generates copy and then just logically disallows usage of the moved value. It relies on LLVM ability to remove unneeded copies.
Upvotes: 0