Skip to content

Commit dc262d9

Browse files
committed
Avoid unnecessary scratch datums for by-copy function arguments
Currently, by-copy function arguments are always stored into a scratch datum, which serves two purposes. First, it is required to be able to have a temporary cleanup, in case that the call fails before the callee actually takes ownership of the value. Second, if the argument is to be passed by reference, the copy is required, so that the function doesn't get a reference to the original value. But in case that the datum does not need a drop glue call and it is passed by value, there's no need to perform the extra copy.
1 parent f348465 commit dc262d9

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

src/librustc/middle/trans/callee.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -826,24 +826,33 @@ pub fn trans_arg_expr(bcx: block,
826826
val = arg_datum.to_ref_llval(bcx);
827827
}
828828
ty::ByCopy => {
829-
debug!("by copy arg with type %s, storing to scratch",
830-
bcx.ty_to_str(arg_datum.ty));
831-
let scratch = scratch_datum(bcx, arg_datum.ty, false);
832-
833-
arg_datum.store_to_datum(bcx,
834-
arg_expr.id,
835-
INIT,
836-
scratch);
837-
838-
// Technically, ownership of val passes to the callee.
839-
// However, we must cleanup should we fail before the
840-
// callee is actually invoked.
841-
scratch.add_clean(bcx);
842-
temp_cleanups.push(scratch.val);
843-
844-
match arg_datum.appropriate_mode() {
845-
ByValue => val = Load(bcx, scratch.val),
846-
ByRef(_) => val = scratch.val,
829+
if ty::type_needs_drop(bcx.tcx(), arg_datum.ty) ||
830+
arg_datum.appropriate_mode().is_by_ref() {
831+
debug!("by copy arg with type %s, storing to scratch",
832+
bcx.ty_to_str(arg_datum.ty));
833+
let scratch = scratch_datum(bcx, arg_datum.ty, false);
834+
835+
arg_datum.store_to_datum(bcx,
836+
arg_expr.id,
837+
INIT,
838+
scratch);
839+
840+
// Technically, ownership of val passes to the callee.
841+
// However, we must cleanup should we fail before the
842+
// callee is actually invoked.
843+
scratch.add_clean(bcx);
844+
temp_cleanups.push(scratch.val);
845+
846+
match scratch.appropriate_mode() {
847+
ByValue => val = Load(bcx, scratch.val),
848+
ByRef(_) => val = scratch.val,
849+
}
850+
} else {
851+
debug!("by copy arg with type %s");
852+
match arg_datum.mode {
853+
ByRef(_) => val = Load(bcx, arg_datum.val),
854+
ByValue => val = arg_datum.val,
855+
}
847856
}
848857
}
849858
}

0 commit comments

Comments
 (0)