@@ -2099,23 +2099,26 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
2099
2099
Store ( cx, src_val, dst) ;
2100
2100
if src. kind == owned { ret zero_alloca ( cx, src. val , t) ; }
2101
2101
// 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;
2103
2104
} else if type_is_structural_or_param ( tcx, t) {
2104
2105
if action == DROP_EXISTING { cx = drop_ty ( cx, dst, t) ; }
2105
2106
cx = memmove_ty ( cx, dst, src_val, t) ;
2106
2107
if src. kind == owned { ret zero_alloca ( cx, src_val, t) ; }
2107
2108
// 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;
2109
2111
}
2110
2112
/* FIXME: suggests a type constraint */
2111
2113
bcx_ccx ( cx) . sess . bug ( "unexpected type in trans::move_val: " +
2112
2114
ty_to_str ( tcx, t) ) ;
2113
2115
}
2114
2116
2115
2117
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 {
2117
2120
// Lvals in memory are not temporaries. Copy them.
2118
- if src. kind != temporary {
2121
+ if src. kind != temporary && !last_use {
2119
2122
let v = src. kind == owned ? load_if_immediate ( cx, src. val , t)
2120
2123
: src. val ;
2121
2124
ret copy_val( cx, action, dst, v, t) ;
@@ -3887,9 +3890,7 @@ fn zero_and_revoke(bcx: @block_ctxt,
3887
3890
for { v, t} in to_zero {
3888
3891
bcx = zero_alloca ( bcx, v, t) ;
3889
3892
}
3890
- for { v, _} in to_revoke {
3891
- bcx = revoke_clean ( bcx, v) ;
3892
- }
3893
+ for { v, _} in to_revoke { revoke_clean ( bcx, v) ; }
3893
3894
ret bcx;
3894
3895
}
3895
3896
@@ -4246,7 +4247,8 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
4246
4247
let { bcx, val: addr , kind } = trans_lval ( src_r. bcx , dst) ;
4247
4248
assert kind == owned;
4248
4249
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 ) ) ;
4250
4252
}
4251
4253
ast:: expr_move ( dst, src) {
4252
4254
// FIXME: calculate copy init-ness in typestate.
@@ -4277,25 +4279,30 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
4277
4279
}
4278
4280
4279
4281
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 ) ;
4281
4283
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) ;
4283
4286
alt dest {
4284
4287
by_val( cell) {
4285
4288
if kind == temporary {
4286
4289
revoke_clean ( bcx, val) ;
4287
4290
* 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 {
4289
4297
if kind == owned { val = Load ( bcx, val) ; }
4290
4298
let { bcx: cx , val } = take_ty_immediate ( bcx, val, ty) ;
4291
4299
* cell = val;
4292
4300
bcx = cx;
4293
- } else {
4294
- bcx = take_ty ( bcx, val, ty) ;
4295
- * cell = Load ( bcx, val) ;
4296
4301
}
4297
4302
}
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
+ }
4299
4306
ignore. { }
4300
4307
}
4301
4308
ret bcx;
@@ -4807,8 +4814,10 @@ fn alloc_local(cx: @block_ctxt, local: @ast::local) -> @block_ctxt {
4807
4814
ast:: pat_bind ( _) { true } _ { false }
4808
4815
} ;
4809
4816
// 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) {
4812
4821
alt local. node . init {
4813
4822
some ( { op: ast:: init_assign. , _} ) { ret cx; }
4814
4823
_ { }
@@ -6027,7 +6036,8 @@ fn write_abi_version(ccx: @crate_ctxt) {
6027
6036
6028
6037
fn trans_crate ( sess : session:: session , crate : @ast:: crate , tcx : ty:: ctxt ,
6029
6038
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 {
6031
6041
let sha = std:: sha1:: mk_sha1 ( ) ;
6032
6042
let link_meta = link:: build_link_meta ( sess, * crate , output, sha) ;
6033
6043
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,
6088
6098
tcx: tcx,
6089
6099
mut_map: mut_map,
6090
6100
copy_map: copy_map,
6101
+ last_uses: last_uses,
6091
6102
stats :
6092
6103
{ mutable n_static_tydescs : 0 u,
6093
6104
mutable n_derived_tydescs : 0 u,
0 commit comments