Avoid superfluous take/drop for temp values passes as arguments

This commit is contained in:
Marijn Haverbeke 2011-07-08 11:02:26 +02:00
parent b41fd61045
commit faec0d7799

View file

@ -5694,12 +5694,23 @@ fn trans_arg_expr(&@block_ctxt cx, &ty::arg arg, TypeRef lldestty0,
auto dst = alloc_ty(bcx, e_ty); auto dst = alloc_ty(bcx, e_ty);
val = dst.val; val = dst.val;
bcx = move_val_if_temp(dst.bcx, INIT, val, lv, e_ty).bcx; bcx = move_val_if_temp(dst.bcx, INIT, val, lv, e_ty).bcx;
} else { } else if (lv.is_mem) {
if (lv.is_mem) { val = load_if_immediate(bcx, val, e_ty); } val = load_if_immediate(bcx, val, e_ty);
// FIXME for non-is-mem lvals, we should be able to just drop the
// cleanup. However, this currently leads to a memory-corrupting
// stage2/rustc . Find out why.
bcx = copy_ty(bcx, val, e_ty).bcx; bcx = copy_ty(bcx, val, e_ty).bcx;
} else {
// Eliding take/drop for appending of external vectors currently
// corrupts memory. I can't figure out why, and external vectors
// are on the way out anyway, so this simply turns off the
// optimization for that case.
auto is_ext_vec_plus = alt (e.node) {
case (ast::expr_binary(_, _, _)) {
ty::type_is_sequence(ccx.tcx, e_ty) &&
!ty::sequence_is_interior(ccx.tcx, e_ty)
}
case (_) { false }
};
if (is_ext_vec_plus) { bcx = copy_ty(bcx, val, e_ty).bcx; }
else { revoke_clean(bcx, val); }
} }
} else if (type_is_immediate(ccx, e_ty) && !lv.is_mem) { } else if (type_is_immediate(ccx, e_ty) && !lv.is_mem) {
val = do_spill(bcx, val); val = do_spill(bcx, val);
@ -6368,11 +6379,8 @@ fn with_out_method(fn(&out_method) -> result work, @block_ctxt cx,
auto reg_val = load_if_immediate(cx, target, t); auto reg_val = load_if_immediate(cx, target, t);
ret drop_ty(cx, reg_val, t); ret drop_ty(cx, reg_val, t);
} }
auto cleanup = bind drop_hoisted_ty(_, res_alloca.val, tp);
find_scope_cx(cx).cleanups += ~[clean_temp(res_alloca.val, cleanup)];
auto done = work(save_in(res_alloca.val)); auto done = work(save_in(res_alloca.val));
auto loaded = load_if_immediate(done.bcx, res_alloca.val, tp); auto loaded = load_if_immediate(done.bcx, res_alloca.val, tp);
revoke_clean(cx, res_alloca.val);
add_clean_temp(cx, loaded, tp); add_clean_temp(cx, loaded, tp);
ret rslt(done.bcx, loaded);; ret rslt(done.bcx, loaded);;
} }