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:
parent
79e9f14abf
commit
39135ecb18
1 changed files with 11 additions and 9 deletions
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue