From faec0d77995cc54944959e807d20b1fdf9bbac59 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 8 Jul 2011 11:02:26 +0200 Subject: [PATCH] Avoid superfluous take/drop for temp values passes as arguments --- src/comp/middle/trans.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 2a23d82c5beb..899a74f573ef 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5694,12 +5694,23 @@ fn trans_arg_expr(&@block_ctxt cx, &ty::arg arg, TypeRef lldestty0, auto dst = alloc_ty(bcx, e_ty); val = dst.val; bcx = move_val_if_temp(dst.bcx, INIT, val, lv, e_ty).bcx; - } else { - if (lv.is_mem) { 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. + } else if (lv.is_mem) { + val = load_if_immediate(bcx, val, e_ty); 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) { 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); 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 loaded = load_if_immediate(done.bcx, res_alloca.val, tp); - revoke_clean(cx, res_alloca.val); add_clean_temp(cx, loaded, tp); ret rslt(done.bcx, loaded);; }