diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2012-01-08 13:32:40 -0800 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2012-01-08 14:57:03 -0800 |
| commit | 7a336f1e7c7c34bb81f80150fb3b04ec0aae14fd (patch) | |
| tree | 33b955867de736e51ea4aa6e1c38a3a32e0e587c /src/comp/middle | |
| parent | 106385cb9140626166a99d11451e5b4912c602c7 (diff) | |
modify last use to take into account cap clause, add new test
Diffstat (limited to 'src/comp/middle')
| -rw-r--r-- | src/comp/middle/last_use.rs | 33 | ||||
| -rw-r--r-- | src/comp/middle/trans_closure.rs | 20 |
2 files changed, 44 insertions, 9 deletions
diff --git a/src/comp/middle/last_use.rs b/src/comp/middle/last_use.rs index f783943c0dc..075c40ccfa5 100644 --- a/src/comp/middle/last_use.rs +++ b/src/comp/middle/last_use.rs @@ -136,6 +136,16 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) { v.visit_expr(dest, cx, v); clear_if_path(cx, dest, v, true); } + expr_fn(_, _, _, cap_clause) { + // n.b.: safe to ignore copies, as if they are unused + // then they are ignored, otherwise they will show up + // as freevars in the body. + + vec::iter(cap_clause.moves) {|ci| + clear_def_if_path(cx, cx.def_map.get(ci.id), true); + } + visit::visit_expr(ex, cx, v); + } expr_call(f, args, _) { v.visit_expr(f, cx, v); let i = 0u, fns = []; @@ -263,18 +273,25 @@ fn clear_in_current(cx: ctx, my_def: node_id, to: bool) { } } +fn clear_def_if_path(cx: ctx, d: def, to: bool) + -> option<node_id> { + alt d { + def_local(def_id, let_copy.) | def_arg(def_id, by_copy.) | + def_arg(def_id, by_move.) { + clear_in_current(cx, def_id.node, to); + some(def_id.node) + } + _ { + none + } + } +} + fn clear_if_path(cx: ctx, ex: @expr, v: visit::vt<ctx>, to: bool) -> option::t<node_id> { alt ex.node { expr_path(_) { - alt cx.def_map.get(ex.id) { - def_local(def_id, let_copy.) | def_arg(def_id, by_copy.) | - def_arg(def_id, by_move.) { - clear_in_current(cx, def_id.node, to); - ret option::some(def_id.node); - } - _ {} - } + ret clear_def_if_path(cx, cx.def_map.get(ex.id), to); } _ { v.visit_expr(ex, cx, v); } } diff --git a/src/comp/middle/trans_closure.rs b/src/comp/middle/trans_closure.rs index 2eb881b09e9..dd343e14b4f 100644 --- a/src/comp/middle/trans_closure.rs +++ b/src/comp/middle/trans_closure.rs @@ -9,6 +9,7 @@ import middle::freevars::{get_freevars, freevar_info}; import option::{some, none}; import back::abi; import syntax::codemap::span; +import syntax::print::pprust::expr_to_str; import back::link::{ mangle_internal_name_by_path, mangle_internal_name_by_path_and_seq}; @@ -121,6 +122,18 @@ tag environment_value { env_ref(ValueRef, ty::t, lval_kind); } +fn ev_to_str(ccx: @crate_ctxt, ev: environment_value) -> str { + alt ev { + env_expr(ex) { expr_to_str(ex) } + env_copy(v, t, lk) { #fmt("copy(%s,%s)", val_str(ccx.tn, v), + ty_to_str(ccx.tcx, t)) } + env_move(v, t, lk) { #fmt("move(%s,%s)", val_str(ccx.tn, v), + ty_to_str(ccx.tcx, t)) } + env_ref(v, t, lk) { #fmt("ref(%s,%s)", val_str(ccx.tn, v), + ty_to_str(ccx.tcx, t)) } + } +} + fn mk_tydesc_ty(tcx: ty::ctxt, ck: ty::closure_kind) -> ty::t { ret alt ck { ty::closure_block. | ty::closure_shared. { ty::mk_type(tcx) } @@ -284,7 +297,7 @@ fn store_environment( }; } - //let ccx = bcx_ccx(bcx); + let ccx = bcx_ccx(bcx); let tcx = bcx_tcx(bcx); // compute the shape of the closure @@ -351,6 +364,11 @@ fn store_environment( let {bcx: bcx, val:bindings_slot} = GEP_tup_like_1(bcx, cboxptr_ty, llbox, [0, abi::cbox_elt_bindings]); vec::iteri(bound_values) { |i, bv| + if (!ccx.sess.get_opts().no_asm_comments) { + add_comment(bcx, #fmt("Copy %s into closure", + ev_to_str(ccx, bv))); + } + let bound_data = GEPi(bcx, bindings_slot, [0, i as int]); alt bv { env_expr(e) { |
