From ea6bb5aafa1827718b143a3657a212cf28e2e08e Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 16 Feb 2012 13:07:53 +0100 Subject: [PATCH] Remove to_zero/to_revoke kludge It is much simpler to just move by_move args into a temporary alloca. --- src/comp/middle/trans/base.rs | 92 +++++++++-------------------------- src/comp/middle/trans/impl.rs | 4 +- 2 files changed, 25 insertions(+), 71 deletions(-) diff --git a/src/comp/middle/trans/base.rs b/src/comp/middle/trans/base.rs index 3b8bde61cb80..17ecf614f1d1 100644 --- a/src/comp/middle/trans/base.rs +++ b/src/comp/middle/trans/base.rs @@ -2731,9 +2731,7 @@ fn trans_cast(cx: @block_ctxt, e: @ast::expr, id: ast::node_id, } fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty: TypeRef, - &to_zero: [{v: ValueRef, t: ty::t}], - &to_revoke: [{v: ValueRef, t: ty::t}], e: @ast::expr) -> - result { + e: @ast::expr) -> result { let ccx = bcx_ccx(cx); let e_ty = expr_ty(cx, e); let is_bot = ty::type_is_bot(e_ty); @@ -2765,19 +2763,20 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty: TypeRef, if arg_mode == ast::by_val && (lv.kind == owned || !imm) { val = Load(bcx, val); } - } else if arg_mode == ast::by_copy { + } else if arg_mode == ast::by_copy || arg_mode == ast::by_move { let {bcx: cx, val: alloc} = alloc_ty(bcx, e_ty); - let last_use = ccx.last_uses.contains_key(e.id); + let move_out = arg_mode == ast::by_move || + ccx.last_uses.contains_key(e.id); bcx = cx; if lv.kind == temporary { revoke_clean(bcx, val); } if lv.kind == owned || !ty::type_is_immediate(e_ty) { bcx = memmove_ty(bcx, alloc, val, e_ty); - if last_use && ty::type_needs_drop(ccx.tcx, e_ty) { + if move_out && ty::type_needs_drop(ccx.tcx, e_ty) { bcx = zero_alloca(bcx, val, e_ty); } } else { Store(bcx, val, alloc); } val = alloc; - if lv.kind != temporary && !last_use { + if lv.kind != temporary && !move_out { bcx = take_ty(bcx, val, e_ty); } } else if ty::type_is_immediate(e_ty) && lv.kind != owned { @@ -2789,15 +2788,6 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty: TypeRef, if !is_bot && arg.ty != e_ty || ty::type_has_params(arg.ty) { val = PointerCast(bcx, val, lldestty); } - - // Collect arg for later if it happens to be one we've moving out. - if arg_mode == ast::by_move { - if lv.kind == owned { - // Use actual ty, not declared ty -- anything else doesn't make - // sense if declared ty is a ty param - to_zero += [{v: lv.val, t: e_ty}]; - } else { to_revoke += [{v: lv.val, t: e_ty}]; } - } ret rslt(bcx, val); } @@ -2813,15 +2803,11 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef, dest: dest) -> {bcx: @block_ctxt, args: [ValueRef], - retslot: ValueRef, - to_zero: [{v: ValueRef, t: ty::t}], - to_revoke: [{v: ValueRef, t: ty::t}]} { + retslot: ValueRef} { let args = ty::ty_fn_args(fn_ty); let llargs: [ValueRef] = []; let lltydescs: [ValueRef] = []; - let to_zero = []; - let to_revoke = []; let ccx = bcx_ccx(cx); let bcx = cx; @@ -2899,17 +2885,14 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef, let arg_tys = type_of_explicit_args(ccx, args); let i = 0u; for e: @ast::expr in es { - let r = trans_arg_expr(bcx, args[i], arg_tys[i], to_zero, to_revoke, - e); + let r = trans_arg_expr(bcx, args[i], arg_tys[i], e); bcx = r.bcx; llargs += [r.val]; i += 1u; } ret {bcx: bcx, args: llargs, - retslot: llretslot, - to_zero: to_zero, - to_revoke: to_revoke}; + retslot: llretslot}; } fn trans_call(in_cx: @block_ctxt, f: @ast::expr, @@ -2969,8 +2952,7 @@ fn trans_call_inner(in_cx: @block_ctxt, fn_expr_ty: ty::t, then one or more of the args has type _|_. Since that means it diverges, the code for the call itself is unreachable. */ - bcx = invoke_full(bcx, faddr, llargs, args_res.to_zero, - args_res.to_revoke); + bcx = invoke_full(bcx, faddr, llargs); alt dest { ignore { if llvm::LLVMIsUndef(llretslot) != lib::llvm::True { @@ -2982,8 +2964,6 @@ fn trans_call_inner(in_cx: @block_ctxt, fn_expr_ty: ty::t, *cell = Load(bcx, llretslot); } } - // Forget about anything we moved out. - bcx = zero_and_revoke(bcx, args_res.to_zero, args_res.to_revoke); bcx = trans_block_cleanups(bcx, cx); let next_cx = new_sub_block_ctxt(in_cx, "next"); @@ -2994,65 +2974,43 @@ fn trans_call_inner(in_cx: @block_ctxt, fn_expr_ty: ty::t, ret next_cx; } -fn zero_and_revoke(bcx: @block_ctxt, - to_zero: [{v: ValueRef, t: ty::t}], - to_revoke: [{v: ValueRef, t: ty::t}]) -> @block_ctxt { - let bcx = bcx; - for {v, t} in to_zero { - bcx = zero_alloca(bcx, v, t); - } - for {v, _} in to_revoke { revoke_clean(bcx, v); } - ret bcx; -} - fn invoke(bcx: @block_ctxt, llfn: ValueRef, llargs: [ValueRef]) -> @block_ctxt { - ret invoke_(bcx, llfn, llargs, [], [], Invoke); + ret invoke_(bcx, llfn, llargs, Invoke); } -fn invoke_full(bcx: @block_ctxt, llfn: ValueRef, llargs: [ValueRef], - to_zero: [{v: ValueRef, t: ty::t}], - to_revoke: [{v: ValueRef, t: ty::t}]) -> @block_ctxt { - ret invoke_(bcx, llfn, llargs, to_zero, to_revoke, Invoke); +fn invoke_full(bcx: @block_ctxt, llfn: ValueRef, llargs: [ValueRef]) + -> @block_ctxt { + ret invoke_(bcx, llfn, llargs, Invoke); } fn invoke_(bcx: @block_ctxt, llfn: ValueRef, llargs: [ValueRef], - to_zero: [{v: ValueRef, t: ty::t}], - to_revoke: [{v: ValueRef, t: ty::t}], invoker: fn(@block_ctxt, ValueRef, [ValueRef], BasicBlockRef, BasicBlockRef)) -> @block_ctxt { // FIXME: May be worth turning this into a plain call when there are no // cleanups to run if bcx.unreachable { ret bcx; } let normal_bcx = new_sub_block_ctxt(bcx, "normal return"); - invoker(bcx, llfn, llargs, normal_bcx.llbb, - get_landing_pad(bcx, to_zero, to_revoke)); + invoker(bcx, llfn, llargs, normal_bcx.llbb, get_landing_pad(bcx)); ret normal_bcx; } -fn get_landing_pad(bcx: @block_ctxt, - to_zero: [{v: ValueRef, t: ty::t}], - to_revoke: [{v: ValueRef, t: ty::t}] - ) -> BasicBlockRef { - let have_zero_or_revoke = vec::is_not_empty(to_zero) - || vec::is_not_empty(to_revoke); - let scope_bcx = find_scope_for_lpad(bcx, have_zero_or_revoke); - if scope_bcx.lpad_dirty || have_zero_or_revoke { +fn get_landing_pad(bcx: @block_ctxt) -> BasicBlockRef { + let scope_bcx = find_scope_for_lpad(bcx); + if scope_bcx.lpad_dirty { let unwind_bcx = new_sub_block_ctxt(bcx, "unwind"); - trans_landing_pad(unwind_bcx, to_zero, to_revoke); + trans_landing_pad(unwind_bcx); scope_bcx.lpad = some(unwind_bcx.llbb); - scope_bcx.lpad_dirty = have_zero_or_revoke; + scope_bcx.lpad_dirty = false; } assert option::is_some(scope_bcx.lpad); ret option::get(scope_bcx.lpad); - fn find_scope_for_lpad(bcx: @block_ctxt, - have_zero_or_revoke: bool) -> @block_ctxt { + fn find_scope_for_lpad(bcx: @block_ctxt) -> @block_ctxt { let scope_bcx = bcx; while true { scope_bcx = find_scope_cx(scope_bcx); - if vec::is_not_empty(scope_bcx.cleanups) - || have_zero_or_revoke { + if vec::is_not_empty(scope_bcx.cleanups) { ret scope_bcx; } else { scope_bcx = alt scope_bcx.parent { @@ -3067,9 +3025,7 @@ fn get_landing_pad(bcx: @block_ctxt, } } -fn trans_landing_pad(bcx: @block_ctxt, - to_zero: [{v: ValueRef, t: ty::t}], - to_revoke: [{v: ValueRef, t: ty::t}]) -> BasicBlockRef { +fn trans_landing_pad(bcx: @block_ctxt) -> BasicBlockRef { // The landing pad return type (the type being propagated). Not sure what // this represents but it's determined by the personality function and // this is what the EH proposal example uses. @@ -3095,7 +3051,7 @@ fn trans_landing_pad(bcx: @block_ctxt, // FIXME: This seems like a very naive and redundant way to generate the // landing pads, as we're re-generating all in-scope cleanups for each // function call. Probably good optimization opportunities here. - let bcx = zero_and_revoke(bcx, to_zero, to_revoke); + let bcx = bcx; let scope_cx = bcx; while true { scope_cx = find_scope_cx(scope_cx); diff --git a/src/comp/middle/trans/impl.rs b/src/comp/middle/trans/impl.rs index f7832eeefaa8..1c4ff2dad848 100644 --- a/src/comp/middle/trans/impl.rs +++ b/src/comp/middle/trans/impl.rs @@ -60,12 +60,10 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident, } fn trans_self_arg(bcx: @block_ctxt, base: @ast::expr) -> result { - let tz = [], tr = []; let basety = expr_ty(bcx, base); let m_by_ref = ast::expl(ast::by_ref); trans_arg_expr(bcx, {mode: m_by_ref, ty: basety}, - T_ptr(type_of_or_i8(bcx_ccx(bcx), basety)), tz, - tr, base) + T_ptr(type_of_or_i8(bcx_ccx(bcx), basety)), base) } fn trans_method_callee(bcx: @block_ctxt, callee_id: ast::node_id,