Skip to content

Commit a35dbf3

Browse files
committed
Don't spill immediates in order to drop them
Issue #1012
1 parent fa12953 commit a35dbf3

File tree

3 files changed

+52
-21
lines changed

3 files changed

+52
-21
lines changed

src/comp/middle/trans.rs

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,9 @@ fn make_take_glue(cx: @block_ctxt, v: ValueRef, t: ty::t) {
13211321
bcx = incr_refcnt_of_boxed(bcx, Load(bcx, v));
13221322
} else if ty::type_is_unique_box(bcx_tcx(bcx), t) {
13231323
check trans_uniq::type_is_unique_box(bcx, t);
1324-
bcx = trans_uniq::duplicate(bcx, v, t);
1324+
let {bcx: cx, val} = trans_uniq::duplicate(bcx, Load(bcx, v), t);
1325+
bcx = cx;
1326+
Store(bcx, val, v);
13251327
} else if ty::type_is_structural(bcx_tcx(bcx), t) {
13261328
bcx = iter_structural_ty(bcx, v, t, take_ty);
13271329
} else if ty::type_is_vec(bcx_tcx(bcx), t) {
@@ -1954,6 +1956,27 @@ fn drop_ty(cx: @block_ctxt, v: ValueRef, t: ty::t) -> @block_ctxt {
19541956
ret cx;
19551957
}
19561958

1959+
fn drop_ty_immediate(bcx: @block_ctxt, v: ValueRef, t: ty::t) -> @block_ctxt {
1960+
alt ty::struct(bcx_tcx(bcx), t) {
1961+
ty::ty_box(_) { ret decr_refcnt_maybe_free(bcx, v, t); }
1962+
ty::ty_uniq(_) { ret free_ty(bcx, v, t); }
1963+
// FIXME A ty_ptr pointing at something that needs drop glue is somehow
1964+
// marked as needing drop glue. This is probably a mistake.
1965+
ty::ty_ptr(_) { ret bcx; }
1966+
}
1967+
}
1968+
1969+
fn take_ty_immediate(bcx: @block_ctxt, v: ValueRef, t: ty::t) -> result {
1970+
alt ty::struct(bcx_tcx(bcx), t) {
1971+
ty::ty_box(_) { ret rslt(incr_refcnt_of_boxed(bcx, v), v); }
1972+
ty::ty_uniq(_) {
1973+
check trans_uniq::type_is_unique_box(bcx, t);
1974+
ret trans_uniq::duplicate(bcx, v, t);
1975+
}
1976+
_ { ret rslt(bcx, v); }
1977+
}
1978+
}
1979+
19571980
fn free_ty(cx: @block_ctxt, v: ValueRef, t: ty::t) -> @block_ctxt {
19581981
if ty::type_has_pointers(bcx_tcx(cx), t) {
19591982
ret call_tydesc_glue(cx, v, t, abi::tydesc_field_free_glue);
@@ -4059,8 +4082,8 @@ fn get_landing_pad(bcx: @block_ctxt,
40594082
let scope_bcx = find_scope_for_lpad(bcx, have_zero_or_revoke);
40604083
if scope_bcx.lpad_dirty || have_zero_or_revoke {
40614084
let unwind_bcx = new_sub_block_ctxt(bcx, "unwind");
4062-
let lpadbb = trans_landing_pad(unwind_bcx, to_zero, to_revoke);
4063-
scope_bcx.lpad = some(lpadbb);
4085+
trans_landing_pad(unwind_bcx, to_zero, to_revoke);
4086+
scope_bcx.lpad = some(unwind_bcx.llbb);
40644087
scope_bcx.lpad_dirty = have_zero_or_revoke;
40654088
}
40664089
assert option::is_some(scope_bcx.lpad);
@@ -4418,10 +4441,15 @@ fn lval_to_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
44184441
let ty = ty::expr_ty(bcx_tcx(bcx), e);
44194442
alt dest {
44204443
by_val(cell) {
4421-
if kind != owned {
4444+
if kind == temporary {
44224445
revoke_clean(bcx, val);
44234446
*cell = val;
4447+
} else if kind == owned_imm {
4448+
let {bcx: cx, val} = take_ty_immediate(bcx, val, ty);
4449+
*cell = val;
4450+
bcx = cx;
44244451
} else if ty::type_is_unique(bcx_tcx(bcx), ty) {
4452+
// FIXME make vectors immediate again, lose this hack
44254453
// Do a song and a dance to work around the fact that take_ty
44264454
// for unique boxes overwrites the pointer.
44274455
let oldval = Load(bcx, val);
@@ -4723,9 +4751,15 @@ fn init_local(bcx: @block_ctxt, local: @ast::local) -> @block_ctxt {
47234751
// This is a local that is kept immediate
47244752
none. {
47254753
let initexpr = alt local.node.init { some({expr, _}) { expr } };
4726-
let val = trans_temp_expr(bcx, initexpr);
4727-
bcx.fcx.lllocals.insert(local.node.pat.id, local_imm(val.val));
4728-
ret val.bcx;
4754+
let {bcx, val, kind} = trans_temp_lval(bcx, initexpr);
4755+
if kind != temporary {
4756+
if kind == owned { val = Load(bcx, val); }
4757+
let rs = take_ty_immediate(bcx, val, ty);
4758+
bcx = rs.bcx; val = rs.val;
4759+
add_clean_temp(bcx, val, ty);
4760+
}
4761+
bcx.fcx.lllocals.insert(local.node.pat.id, local_imm(val));
4762+
ret bcx;
47294763
}
47304764
};
47314765

@@ -4984,8 +5018,7 @@ fn alloc_local(cx: @block_ctxt, local: @ast::local) -> @block_ctxt {
49845018
};
49855019
// Do not allocate space for locals that can be kept immediate.
49865020
if is_simple && !bcx_ccx(cx).mut_map.contains_key(local.node.pat.id) &&
4987-
ty::type_is_immediate(bcx_tcx(cx), t) &&
4988-
!ty::type_needs_drop(bcx_tcx(cx), t) {
5021+
ty::type_is_immediate(bcx_tcx(cx), t) {
49895022
alt local.node.init {
49905023
some({op: ast::init_assign., _}) { ret cx; }
49915024
_ {}

src/comp/middle/trans_common.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -271,17 +271,17 @@ fn add_clean(cx: @block_ctxt, val: ValueRef, ty: ty::t) {
271271
}
272272
fn add_clean_temp(cx: @block_ctxt, val: ValueRef, ty: ty::t) {
273273
if !ty::type_needs_drop(bcx_tcx(cx), ty) { ret; }
274-
fn spill_and_drop(cx: @block_ctxt, val: ValueRef, ty: ty::t) ->
274+
fn do_drop(bcx: @block_ctxt, val: ValueRef, ty: ty::t) ->
275275
@block_ctxt {
276-
let bcx = cx;
277-
let r = trans::spill_if_immediate(bcx, val, ty);
278-
let spilled = r.val;
279-
bcx = r.bcx;
280-
ret drop_ty(bcx, spilled, ty);
276+
if ty::type_is_immediate(bcx_tcx(bcx), ty) {
277+
ret trans::drop_ty_immediate(bcx, val, ty);
278+
} else {
279+
ret drop_ty(bcx, val, ty);
280+
}
281281
}
282282
let scope_cx = find_scope_cx(cx);
283283
scope_cx.cleanups +=
284-
[clean_temp(val, bind spill_and_drop(_, val, ty))];
284+
[clean_temp(val, bind do_drop(_, val, ty))];
285285
scope_cx.lpad_dirty = true;
286286
}
287287
fn add_clean_temp_mem(cx: @block_ctxt, val: ValueRef, ty: ty::t) {

src/comp/middle/trans_uniq.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,13 @@ fn autoderef(bcx: @block_ctxt, v: ValueRef, t: ty::t)
9898
}
9999

100100
fn duplicate(bcx: @block_ctxt, v: ValueRef, t: ty::t)
101-
: type_is_unique_box(bcx, t) -> @block_ctxt {
101+
: type_is_unique_box(bcx, t) -> result {
102102

103103
let content_ty = content_ty(bcx, t);
104104
let {bcx, val: llptr} = alloc_uniq(bcx, t);
105105

106-
let src = Load(bcx, v);
107-
let src = load_if_immediate(bcx, src, content_ty);
106+
let src = load_if_immediate(bcx, v, content_ty);
108107
let dst = llptr;
109108
let bcx = trans::copy_val(bcx, INIT, dst, src, content_ty);
110-
Store(bcx, dst, v);
111-
ret bcx;
109+
ret rslt(bcx, dst);
112110
}

0 commit comments

Comments
 (0)