Skip to content

Commit f41a8e7

Browse files
committed
---
yaml --- r: 6378 b: refs/heads/master c: 68db68c h: refs/heads/master v: v3
1 parent ea15f3e commit f41a8e7

File tree

5 files changed

+49
-26
lines changed

5 files changed

+49
-26
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: f6491bb42636f4c43f3cbb48fdb98ddd749e6e5d
2+
refs/heads/master: 68db68c4cccb9204e91ffcd08fd27be0f33f0033

trunk/src/comp/driver/rustc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
161161
let llmod =
162162
time(time_passes, "translation",
163163
bind trans::trans_crate(sess, crate, ty_cx, output, ast_map,
164-
mut_map, copy_map));
164+
mut_map, copy_map, last_uses));
165165
time(time_passes, "LLVM passes",
166166
bind link::write::run_passes(sess, llmod, output));
167167
}

trunk/src/comp/middle/last_use.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ fn find_last_uses(c: @crate, def_map: resolve::def_map, tcx: ty::ctxt)
3131
mutable blocks: nil};
3232
visit::visit_crate(*c, cx, v);
3333
let mini_table = std::map::new_int_hash();
34-
cx.last_uses.items {|key, val| if val { mini_table.insert(key, ()); }}
34+
cx.last_uses.items {|key, val|
35+
if val {
36+
mini_table.insert(key, ());
37+
let def_node = ast_util::def_id_of_def(def_map.get(key)).node;
38+
mini_table.insert(def_node, ());
39+
}
40+
}
3541
ret mini_table;
3642
}
3743

trunk/src/comp/middle/trans.rs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,23 +2099,26 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
20992099
Store(cx, src_val, dst);
21002100
if src.kind == owned { ret zero_alloca(cx, src.val, t); }
21012101
// If we're here, it must be a temporary.
2102-
ret revoke_clean(cx, src_val);
2102+
revoke_clean(cx, src_val);
2103+
ret cx;
21032104
} else if type_is_structural_or_param(tcx, t) {
21042105
if action == DROP_EXISTING { cx = drop_ty(cx, dst, t); }
21052106
cx = memmove_ty(cx, dst, src_val, t);
21062107
if src.kind == owned { ret zero_alloca(cx, src_val, t); }
21072108
// If we're here, it must be a temporary.
2108-
ret revoke_clean(cx, src_val);
2109+
revoke_clean(cx, src_val);
2110+
ret cx;
21092111
}
21102112
/* FIXME: suggests a type constraint */
21112113
bcx_ccx(cx).sess.bug("unexpected type in trans::move_val: " +
21122114
ty_to_str(tcx, t));
21132115
}
21142116

21152117
fn store_temp_expr(cx: @block_ctxt, action: copy_action, dst: ValueRef,
2116-
src: lval_result, t: ty::t) -> @block_ctxt {
2118+
src: lval_result, t: ty::t, last_use: bool)
2119+
-> @block_ctxt {
21172120
// Lvals in memory are not temporaries. Copy them.
2118-
if src.kind != temporary {
2121+
if src.kind != temporary && !last_use {
21192122
let v = src.kind == owned ? load_if_immediate(cx, src.val, t)
21202123
: src.val;
21212124
ret copy_val(cx, action, dst, v, t);
@@ -3887,9 +3890,7 @@ fn zero_and_revoke(bcx: @block_ctxt,
38873890
for {v, t} in to_zero {
38883891
bcx = zero_alloca(bcx, v, t);
38893892
}
3890-
for {v, _} in to_revoke {
3891-
bcx = revoke_clean(bcx, v);
3892-
}
3893+
for {v, _} in to_revoke { revoke_clean(bcx, v); }
38933894
ret bcx;
38943895
}
38953896

@@ -4246,7 +4247,8 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
42464247
let {bcx, val: addr, kind} = trans_lval(src_r.bcx, dst);
42474248
assert kind == owned;
42484249
ret store_temp_expr(bcx, DROP_EXISTING, addr, src_r,
4249-
ty::expr_ty(bcx_tcx(bcx), src));
4250+
ty::expr_ty(bcx_tcx(bcx), src),
4251+
bcx_ccx(bcx).last_uses.contains_key(src.id));
42504252
}
42514253
ast::expr_move(dst, src) {
42524254
// FIXME: calculate copy init-ness in typestate.
@@ -4277,25 +4279,30 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
42774279
}
42784280

42794281
fn lval_to_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
4280-
let lv = trans_lval(bcx, e);
4282+
let lv = trans_lval(bcx, e), ccx = bcx_ccx(bcx);
42814283
let {bcx, val, kind} = lv;
4282-
let ty = ty::expr_ty(bcx_tcx(bcx), e);
4284+
let last_use = kind == owned && ccx.last_uses.contains_key(e.id);
4285+
let ty = ty::expr_ty(ccx.tcx, e);
42834286
alt dest {
42844287
by_val(cell) {
42854288
if kind == temporary {
42864289
revoke_clean(bcx, val);
42874290
*cell = val;
4288-
} else if ty::type_is_immediate(bcx_tcx(bcx), ty) {
4291+
} else if last_use {
4292+
*cell = Load(bcx, val);
4293+
if ty::type_needs_drop(ccx.tcx, ty) {
4294+
bcx = zero_alloca(bcx, val, ty);
4295+
}
4296+
} else {
42894297
if kind == owned { val = Load(bcx, val); }
42904298
let {bcx: cx, val} = take_ty_immediate(bcx, val, ty);
42914299
*cell = val;
42924300
bcx = cx;
4293-
} else {
4294-
bcx = take_ty(bcx, val, ty);
4295-
*cell = Load(bcx, val);
42964301
}
42974302
}
4298-
save_in(loc) { bcx = store_temp_expr(bcx, INIT, loc, lv, ty); }
4303+
save_in(loc) {
4304+
bcx = store_temp_expr(bcx, INIT, loc, lv, ty, last_use);
4305+
}
42994306
ignore. {}
43004307
}
43014308
ret bcx;
@@ -4807,8 +4814,10 @@ fn alloc_local(cx: @block_ctxt, local: @ast::local) -> @block_ctxt {
48074814
ast::pat_bind(_) { true } _ { false }
48084815
};
48094816
// Do not allocate space for locals that can be kept immediate.
4810-
if is_simple && !bcx_ccx(cx).mut_map.contains_key(local.node.pat.id) &&
4811-
ty::type_is_immediate(bcx_tcx(cx), t) {
4817+
let ccx = bcx_ccx(cx);
4818+
if is_simple && !ccx.mut_map.contains_key(local.node.pat.id) &&
4819+
!ccx.last_uses.contains_key(local.node.pat.id) &&
4820+
ty::type_is_immediate(ccx.tcx, t) {
48124821
alt local.node.init {
48134822
some({op: ast::init_assign., _}) { ret cx; }
48144823
_ {}
@@ -6027,7 +6036,8 @@ fn write_abi_version(ccx: @crate_ctxt) {
60276036

60286037
fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
60296038
output: str, amap: ast_map::map, mut_map: mut::mut_map,
6030-
copy_map: alias::copy_map) -> ModuleRef {
6039+
copy_map: alias::copy_map, last_uses: last_use::last_uses)
6040+
-> ModuleRef {
60316041
let sha = std::sha1::mk_sha1();
60326042
let link_meta = link::build_link_meta(sess, *crate, output, sha);
60336043
let llmod = str::as_buf(link_meta.name, {|buf|
@@ -6088,6 +6098,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
60886098
tcx: tcx,
60896099
mut_map: mut_map,
60906100
copy_map: copy_map,
6101+
last_uses: last_uses,
60916102
stats:
60926103
{mutable n_static_tydescs: 0u,
60936104
mutable n_derived_tydescs: 0u,

trunk/src/comp/middle/trans_common.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ type crate_ctxt =
102102
tcx: ty::ctxt,
103103
mut_map: mut::mut_map,
104104
copy_map: alias::copy_map,
105+
last_uses: last_use::last_uses,
105106
stats: stats,
106107
upcalls: @upcall::upcalls,
107108
rust_object_type: TypeRef,
@@ -283,7 +284,7 @@ fn add_clean_free(cx: @block_ctxt, ptr: ValueRef, shared: bool) {
283284
// to a system where we can also cancel the cleanup on local variables, but
284285
// this will be more involved. For now, we simply zero out the local, and the
285286
// drop glue checks whether it is zero.
286-
fn revoke_clean(cx: @block_ctxt, val: ValueRef) -> @block_ctxt {
287+
fn revoke_clean(cx: @block_ctxt, val: ValueRef) {
287288
let sc_cx = find_scope_cx(cx);
288289
let found = -1;
289290
let i = 0;
@@ -296,16 +297,21 @@ fn revoke_clean(cx: @block_ctxt, val: ValueRef) -> @block_ctxt {
296297
}
297298
i += 1;
298299
}
299-
// The value does not have a cleanup associated with it. Might be a
300-
// constant or some immediate value.
301-
if found == -1 { ret cx; }
300+
// The value does not have a cleanup associated with it. Continue to next
301+
// scope.
302+
if found == -1 {
303+
alt sc_cx.parent {
304+
parent_some(parent) { revoke_clean(parent, val); } _ {}
305+
}
306+
ret;
307+
}
302308
// We found the cleanup and remove it
303309
sc_cx.cleanups =
304310
std::vec::slice(sc_cx.cleanups, 0u, found as uint) +
305311
std::vec::slice(sc_cx.cleanups, (found as uint) + 1u,
306312
std::vec::len(sc_cx.cleanups));
307313
sc_cx.lpad_dirty = true;
308-
ret cx;
314+
ret;
309315
}
310316

311317
fn get_res_dtor(ccx: @crate_ctxt, sp: span, did: ast::def_id, inner_t: ty::t)

0 commit comments

Comments
 (0)