1
Fork 0

Omit unnecessary stack slots for ignored return values

If we have an immediate return value that doesn't need to be dropped, we
don't have to create a stack slot for it.
This commit is contained in:
Björn Steinbrink 2014-07-28 08:23:16 +02:00
parent 79e9f14abf
commit 39135ecb18

View file

@ -775,6 +775,8 @@ pub fn trans_call_inner<'a>(
// We trans them in place in `trans_intrinsic_call` // We trans them in place in `trans_intrinsic_call`
assert!(abi != synabi::RustIntrinsic); assert!(abi != synabi::RustIntrinsic);
let is_rust_fn = abi == synabi::Rust || abi == synabi::RustCall;
// Generate a location to store the result. If the user does // Generate a location to store the result. If the user does
// not care about the result, just make a stack slot. // not care about the result, just make a stack slot.
let opt_llretslot = match dest { let opt_llretslot = match dest {
@ -783,7 +785,9 @@ pub fn trans_call_inner<'a>(
None None
} }
Some(expr::SaveIn(dst)) => Some(dst), Some(expr::SaveIn(dst)) => Some(dst),
Some(expr::Ignore) => { Some(expr::Ignore) if !is_rust_fn ||
type_of::return_uses_outptr(ccx, ret_ty) ||
ty::type_needs_drop(bcx.tcx(), ret_ty) => {
if !type_is_zero_size(ccx, ret_ty) { if !type_is_zero_size(ccx, ret_ty) {
Some(alloc_ty(bcx, ret_ty, "__llret")) Some(alloc_ty(bcx, ret_ty, "__llret"))
} else { } else {
@ -791,6 +795,7 @@ pub fn trans_call_inner<'a>(
Some(C_undef(llty.ptr_to())) Some(C_undef(llty.ptr_to()))
} }
} }
Some(expr::Ignore) => None
}; };
let mut llresult = unsafe { let mut llresult = unsafe {
@ -803,7 +808,7 @@ pub fn trans_call_inner<'a>(
// and done, either the return value of the function will have been // and done, either the return value of the function will have been
// written in opt_llretslot (if it is Some) or `llresult` will be // written in opt_llretslot (if it is Some) or `llresult` will be
// set appropriately (otherwise). // set appropriately (otherwise).
if abi == synabi::Rust || abi == synabi::RustCall { if is_rust_fn {
let mut llargs = Vec::new(); let mut llargs = Vec::new();
// Push the out-pointer if we use an out-pointer for this // Push the out-pointer if we use an out-pointer for this
@ -878,15 +883,12 @@ pub fn trans_call_inner<'a>(
// If the caller doesn't care about the result of this fn call, // If the caller doesn't care about the result of this fn call,
// drop the temporary slot we made. // drop the temporary slot we made.
match dest { match (dest, opt_llretslot) {
None => { (Some(expr::Ignore), Some(llretslot)) => {
assert!(!type_of::return_uses_outptr(bcx.ccx(), ret_ty));
}
Some(expr::Ignore) => {
// drop the value if it is not being saved. // drop the value if it is not being saved.
bcx = glue::drop_ty(bcx, opt_llretslot.unwrap(), ret_ty); bcx = glue::drop_ty(bcx, llretslot, ret_ty);
} }
Some(expr::SaveIn(_)) => { } _ => {}
} }
if ty::type_is_bot(ret_ty) { if ty::type_is_bot(ret_ty) {