From 2790ab5f79e217abb76b05a6bdd433cd133b8cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Wed, 19 Jun 2013 20:28:42 +0200 Subject: [PATCH] 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. Reduces the time for the LLVM passes when compiling librustc by about 10%. --- src/librustc/middle/trans/callee.rs | 43 ++++++++++++++++++----------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index bfbe078c4f524..27fffeeeb1eca 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -828,22 +828,33 @@ pub fn trans_arg_expr(bcx: block, ty::ByCopy => { debug!("by copy arg with type %s, storing to scratch", bcx.ty_to_str(arg_datum.ty)); - let scratch = scratch_datum(bcx, arg_datum.ty, false); - - arg_datum.store_to_datum(bcx, - arg_expr.id, - INIT, - scratch); - - // Technically, ownership of val passes to the callee. - // However, we must cleanup should we fail before the - // callee is actually invoked. - scratch.add_clean(bcx); - temp_cleanups.push(scratch.val); - - match arg_datum.appropriate_mode() { - ByValue => val = Load(bcx, scratch.val), - ByRef(_) => val = scratch.val, + if ty::type_needs_drop(bcx.tcx(), arg_datum.ty) || + arg_datum.appropriate_mode().is_by_ref() { + debug!("by copy arg with type %s, storing to scratch", + bcx.ty_to_str(arg_datum.ty)); + let scratch = scratch_datum(bcx, arg_datum.ty, false); + + arg_datum.store_to_datum(bcx, + arg_expr.id, + INIT, + scratch); + + // Technically, ownership of val passes to the callee. + // However, we must cleanup should we fail before the + // callee is actually invoked. + scratch.add_clean(bcx); + temp_cleanups.push(scratch.val); + + match scratch.appropriate_mode() { + ByValue => val = Load(bcx, scratch.val), + ByRef(_) => val = scratch.val, + } + } else { + debug!("by copy arg with type %s"); + match arg_datum.mode { + ByRef(_) => val = Load(bcx, arg_datum.val), + ByValue => val = arg_datum.val, + } } } }