Skip to content

Commit 9a32064

Browse files
committed
---
yaml --- r: 4878 b: refs/heads/master c: 081caf5 h: refs/heads/master v: v3
1 parent aa88d00 commit 9a32064

File tree

3 files changed

+93
-94
lines changed

3 files changed

+93
-94
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: c930af74d5ad02cee4a540b0d0a91b12b3d6e58c
2+
refs/heads/master: 081caf5bb8e22102ba517c7484dafcf65705c681

trunk/src/comp/middle/trans.rs

Lines changed: 87 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -2086,7 +2086,6 @@ fn lazily_emit_tydesc_glue(cx: &@block_ctxt, field: int,
20862086
make_generic_glue(lcx, cx.sp, ti.ty, glue_fn,
20872087
copy_helper(make_copy_glue),
20882088
ti.ty_params, "copy");
2089-
20902089
}
20912090
}
20922091
}
@@ -2319,8 +2318,34 @@ fn duplicate_heap_parts_if_necessary(cx: &@block_ctxt, vptr: ValueRef,
23192318

23202319
tag copy_action { INIT; DROP_EXISTING; }
23212320

2321+
// These are the types that are passed by pointer.
2322+
fn type_is_structural_or_param(tcx: &ty::ctxt, t: ty::t) -> bool {
2323+
if ty::type_is_structural(tcx, t) { ret true; }
2324+
alt ty::struct(tcx, t) {
2325+
ty::ty_param(_, _) { ret true; }
2326+
_ { ret false; }
2327+
}
2328+
}
2329+
23222330
fn copy_val(cx: &@block_ctxt, action: copy_action, dst: ValueRef,
2323-
src: ValueRef, t: &ty::t) -> result {
2331+
src: ValueRef, t: &ty::t) -> @block_ctxt {
2332+
if type_is_structural_or_param(bcx_ccx(cx).tcx, t) &&
2333+
action == DROP_EXISTING {
2334+
let do_copy_cx = new_sub_block_ctxt(cx, "do_copy");
2335+
let next_cx = new_sub_block_ctxt(cx, "next");
2336+
let self_assigning =
2337+
cx.build.ICmp(lib::llvm::LLVMIntNE,
2338+
cx.build.PointerCast(dst, val_ty(src)), src);
2339+
cx.build.CondBr(self_assigning, do_copy_cx.llbb, next_cx.llbb);
2340+
do_copy_cx = copy_val_no_check(do_copy_cx, action, dst, src, t);
2341+
do_copy_cx.build.Br(next_cx.llbb);
2342+
ret next_cx;
2343+
}
2344+
ret copy_val_no_check(cx, action, dst, src, t);
2345+
}
2346+
2347+
fn copy_val_no_check(cx: &@block_ctxt, action: copy_action, dst: ValueRef,
2348+
src: ValueRef, t: &ty::t) -> @block_ctxt {
23242349
let ccx = bcx_ccx(cx);
23252350
// FIXME this is just a clunky stopgap. we should do proper checking in an
23262351
// earlier pass.
@@ -2329,36 +2354,26 @@ fn copy_val(cx: &@block_ctxt, action: copy_action, dst: ValueRef,
23292354
}
23302355

23312356
if ty::type_is_scalar(ccx.tcx, t) || ty::type_is_native(ccx.tcx, t) {
2332-
ret rslt(cx, cx.build.Store(src, dst));
2357+
cx.build.Store(src, dst);
2358+
ret cx;
23332359
} else if ty::type_is_nil(ccx.tcx, t) || ty::type_is_bot(ccx.tcx, t) {
2334-
ret rslt(cx, C_nil());
2360+
ret cx;
23352361
} else if ty::type_is_boxed(ccx.tcx, t) {
2336-
let bcx;
2337-
if action == DROP_EXISTING {
2338-
bcx = drop_ty(cx, cx.build.Load(dst), t).bcx;
2339-
} else { bcx = cx; }
2362+
let bcx = if action == DROP_EXISTING {
2363+
drop_ty(cx, cx.build.Load(dst), t).bcx
2364+
} else { cx };
23402365
bcx = take_ty(bcx, src, t).bcx;
2341-
ret rslt(bcx, bcx.build.Store(src, dst));
2342-
} else if ty::type_is_structural(ccx.tcx, t) ||
2343-
ty::type_has_dynamic_size(ccx.tcx, t) {
2344-
// Check for self-assignment.
2345-
let do_copy_cx = new_sub_block_ctxt(cx, "do_copy");
2346-
let next_cx = new_sub_block_ctxt(cx, "next");
2347-
let self_assigning =
2348-
cx.build.ICmp(lib::llvm::LLVMIntNE,
2349-
cx.build.PointerCast(dst, val_ty(src)), src);
2350-
cx.build.CondBr(self_assigning, do_copy_cx.llbb, next_cx.llbb);
2351-
2352-
if action == DROP_EXISTING {
2353-
do_copy_cx = drop_ty(do_copy_cx, dst, t).bcx;
2354-
}
2355-
do_copy_cx = memmove_ty(do_copy_cx, dst, src, t).bcx;
2356-
do_copy_cx = take_ty(do_copy_cx, dst, t).bcx;
2357-
do_copy_cx.build.Br(next_cx.llbb);
2358-
2359-
ret rslt(next_cx, C_nil());
2360-
}
2361-
ccx.sess.bug("unexpected type in trans::copy_val: " +
2366+
bcx.build.Store(src, dst);
2367+
ret bcx;
2368+
} else if type_is_structural_or_param(ccx.tcx, t) {
2369+
let bcx = if action == DROP_EXISTING {
2370+
drop_ty(cx, dst, t).bcx
2371+
} else { cx };
2372+
bcx = memmove_ty(bcx, dst, src, t).bcx;
2373+
bcx = take_ty(bcx, dst, t).bcx;
2374+
ret bcx;
2375+
}
2376+
ccx.sess.bug("unexpected type in trans::copy_val_no_check: " +
23622377
ty_to_str(ccx.tcx, t));
23632378
}
23642379

@@ -2368,47 +2383,46 @@ fn copy_val(cx: &@block_ctxt, action: copy_action, dst: ValueRef,
23682383
// FIXME: We always zero out the source. Ideally we would detect the
23692384
// case where a variable is always deinitialized by block exit and thus
23702385
// doesn't need to be dropped.
2371-
// FIXME: This can return only a block_ctxt, not a result.
23722386
fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
2373-
src: &lval_result, t: &ty::t) -> result {
2387+
src: &lval_result, t: &ty::t) -> @block_ctxt {
23742388
let src_val = src.res.val;
23752389
if ty::type_is_scalar(bcx_tcx(cx), t) ||
23762390
ty::type_is_native(bcx_tcx(cx), t) {
23772391
if src.is_mem { src_val = cx.build.Load(src_val); }
23782392
cx.build.Store(src_val, dst);
2379-
ret rslt(cx, C_nil());
2393+
ret cx;
23802394
} else if ty::type_is_nil(bcx_tcx(cx), t) ||
23812395
ty::type_is_bot(bcx_tcx(cx), t) {
2382-
ret rslt(cx, C_nil());
2396+
ret cx;
23832397
} else if ty::type_is_unique(bcx_tcx(cx), t) ||
23842398
ty::type_is_boxed(bcx_tcx(cx), t) {
23852399
if src.is_mem { src_val = cx.build.Load(src_val); }
23862400
if action == DROP_EXISTING {
23872401
cx = drop_ty(cx, cx.build.Load(dst), t).bcx;
23882402
}
23892403
cx.build.Store(src_val, dst);
2390-
if src.is_mem { ret zero_alloca(cx, src.res.val, t); }
2404+
if src.is_mem { ret zero_alloca(cx, src.res.val, t).bcx; }
23912405

23922406
// If we're here, it must be a temporary.
23932407
revoke_clean(cx, src_val);
2394-
ret rslt(cx, C_nil());
2408+
ret cx;
23952409
} else if ty::type_is_structural(bcx_tcx(cx), t) ||
23962410
ty::type_has_dynamic_size(bcx_tcx(cx), t) {
23972411
if action == DROP_EXISTING { cx = drop_ty(cx, dst, t).bcx; }
23982412
cx = memmove_ty(cx, dst, src_val, t).bcx;
23992413
if src.is_mem {
2400-
ret zero_alloca(cx, src_val, t);
2414+
ret zero_alloca(cx, src_val, t).bcx;
24012415
} else { // Temporary value
24022416
revoke_clean(cx, src_val);
2403-
ret rslt(cx, C_nil());
2417+
ret cx;
24042418
}
24052419
}
24062420
bcx_ccx(cx).sess.bug("unexpected type in trans::move_val: " +
24072421
ty_to_str(bcx_tcx(cx), t));
24082422
}
24092423

24102424
fn move_val_if_temp(cx: @block_ctxt, action: copy_action, dst: ValueRef,
2411-
src: &lval_result, t: &ty::t) -> result {
2425+
src: &lval_result, t: &ty::t) -> @block_ctxt {
24122426

24132427
// Lvals in memory are not temporaries. Copy them.
24142428
if src.is_mem {
@@ -2560,8 +2574,8 @@ fn trans_unary(cx: &@block_ctxt, op: ast::unop, e: &@ast::expr,
25602574
let llety = T_ptr(type_of(bcx_ccx(sub.bcx), e.span, e_ty));
25612575
body = sub.bcx.build.PointerCast(body, llety);
25622576
}
2563-
let res = move_val_if_temp(sub.bcx, INIT, body, lv, e_ty);
2564-
ret rslt(res.bcx, sub.box);
2577+
let bcx = move_val_if_temp(sub.bcx, INIT, body, lv, e_ty);
2578+
ret rslt(bcx, sub.box);
25652579
}
25662580
ast::deref. {
25672581
bcx_ccx(cx).sess.bug("deref expressions should have been \
@@ -2901,10 +2915,8 @@ mod ivec {
29012915
let copy_src =
29022916
load_if_immediate(copy_loop_body_cx, copy_src_ptr, unit_ty);
29032917

2904-
rs =
2905-
copy_val(copy_loop_body_cx, INIT, copy_dest_ptr, copy_src,
2906-
unit_ty);
2907-
let post_copy_cx = rs.bcx;
2918+
let post_copy_cx = copy_val
2919+
(copy_loop_body_cx, INIT, copy_dest_ptr, copy_src, unit_ty);
29082920
// Increment both pointers.
29092921
if ty::type_has_dynamic_size(bcx_tcx(cx), t) {
29102922
// We have to increment by the dynamically-computed size.
@@ -3104,10 +3116,8 @@ mod ivec {
31043116
rhs_copy_cx.llbb);
31053117
let dest_ptr_lhs_copy = lhs_do_copy_cx.build.Load(dest_ptr_ptr);
31063118
let lhs_val = load_if_immediate(lhs_do_copy_cx, lhs_ptr, unit_ty);
3107-
rs =
3108-
copy_val(lhs_do_copy_cx, INIT, dest_ptr_lhs_copy, lhs_val,
3109-
unit_ty);
3110-
lhs_do_copy_cx = rs.bcx;
3119+
lhs_do_copy_cx = copy_val(lhs_do_copy_cx, INIT, dest_ptr_lhs_copy,
3120+
lhs_val, unit_ty);
31113121

31123122
// Increment both pointers.
31133123
if ty::type_has_dynamic_size(bcx_tcx(cx), unit_ty) {
@@ -3133,10 +3143,8 @@ mod ivec {
31333143
next_cx.llbb);
31343144
let dest_ptr_rhs_copy = rhs_do_copy_cx.build.Load(dest_ptr_ptr);
31353145
let rhs_val = load_if_immediate(rhs_do_copy_cx, rhs_ptr, unit_ty);
3136-
rs =
3137-
copy_val(rhs_do_copy_cx, INIT, dest_ptr_rhs_copy, rhs_val,
3138-
unit_ty);
3139-
rhs_do_copy_cx = rs.bcx;
3146+
rhs_do_copy_cx = copy_val(rhs_do_copy_cx, INIT, dest_ptr_rhs_copy,
3147+
rhs_val, unit_ty);
31403148

31413149
// Increment both pointers.
31423150
if ty::type_has_dynamic_size(bcx_tcx(cx), unit_ty) {
@@ -3227,8 +3235,8 @@ fn trans_evec_add(cx: &@block_ctxt, t: &ty::t, lhs: ValueRef, rhs: ValueRef)
32273235
-> result {
32283236
let r = alloc_ty(cx, t);
32293237
let tmp = r.val;
3230-
r = copy_val(r.bcx, INIT, tmp, lhs, t);
3231-
let bcx = trans_evec_append(r.bcx, t, tmp, rhs).bcx;
3238+
let bcx = copy_val(r.bcx, INIT, tmp, lhs, t);
3239+
let bcx = trans_evec_append(bcx, t, tmp, rhs).bcx;
32323240
tmp = load_if_immediate(bcx, tmp, t);
32333241
add_clean_temp(cx, tmp, t);
32343242
ret rslt(bcx, tmp);
@@ -3486,10 +3494,10 @@ fn trans_for(cx: &@block_ctxt, local: &@ast::local, seq: &@ast::expr,
34863494
outer_next_cx, "for loop scope");
34873495
cx.build.Br(scope_cx.llbb);
34883496
let local_res = alloc_local(scope_cx, local);
3489-
let loc_r = copy_val(local_res.bcx, INIT, local_res.val, curr, t);
3497+
let bcx = copy_val(local_res.bcx, INIT, local_res.val, curr, t);
34903498
add_clean(scope_cx, local_res.val, t);
34913499
let bcx =
3492-
trans_alt::bind_irrefutable_pat(loc_r.bcx, local.node.pat,
3500+
trans_alt::bind_irrefutable_pat(bcx, local.node.pat,
34933501
local_res.val, cx.fcx.lllocals,
34943502
false);
34953503
bcx = trans_block(bcx, body, return).bcx;
@@ -3587,8 +3595,7 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
35873595
GEP_tup_like(bcx, bindings_ty, bindings.val, [0, i as int]);
35883596
bcx = bound.bcx;
35893597
if copying {
3590-
bcx =
3591-
move_val_if_temp(bcx, INIT, bound.val, lv, bound_tys[i]).bcx;
3598+
bcx = move_val_if_temp(bcx, INIT, bound.val, lv, bound_tys[i]);
35923599
} else { bcx.build.Store(lv.res.val, bound.val); }
35933600
i += 1u;
35943601
}
@@ -4548,7 +4555,7 @@ fn trans_arg_expr(cx: &@block_ctxt, arg: &ty::arg, lldestty0: TypeRef,
45484555
// Do nothing for temporaries, just give them to callee
45494556
} else if ty::type_is_structural(ccx.tcx, e_ty) {
45504557
let dst = alloc_ty(bcx, e_ty);
4551-
bcx = copy_val(dst.bcx, INIT, dst.val, val, e_ty).bcx;
4558+
bcx = copy_val(dst.bcx, INIT, dst.val, val, e_ty);
45524559
val = dst.val;
45534560
add_clean_temp(bcx, val, e_ty);
45544561
} else {
@@ -4797,7 +4804,7 @@ fn trans_tup(cx: &@block_ctxt, elts: &[@ast::expr], id: ast::node_id) ->
47974804
let src = trans_lval(bcx, e);
47984805
bcx = src.res.bcx;
47994806
let dst_res = GEP_tup_like(bcx, t, tup_val, [0, i]);
4800-
bcx = move_val_if_temp(dst_res.bcx, INIT, dst_res.val, src, e_ty).bcx;
4807+
bcx = move_val_if_temp(dst_res.bcx, INIT, dst_res.val, src, e_ty);
48014808
i += 1;
48024809
}
48034810
ret rslt(bcx, tup_val);
@@ -4891,7 +4898,7 @@ fn trans_ivec(bcx: @block_ctxt, args: &[@ast::expr], id: ast::node_id) ->
48914898
} else {
48924899
lleltptr = bcx.build.InBoundsGEP(llfirsteltptr, [C_uint(i)]);
48934900
}
4894-
bcx = move_val_if_temp(bcx, INIT, lleltptr, lv, unit_ty).bcx;
4901+
bcx = move_val_if_temp(bcx, INIT, lleltptr, lv, unit_ty);
48954902
i += 1u;
48964903
}
48974904
ret rslt(bcx, llvecptr);
@@ -4926,19 +4933,16 @@ fn trans_rec(cx: &@block_ctxt, fields: &[ast::field],
49264933
if str::eq(f.node.ident, tf.ident) {
49274934
expr_provided = true;
49284935
let lv = trans_lval(bcx, f.node.expr);
4929-
bcx =
4930-
move_val_if_temp(lv.res.bcx, INIT, dst_res.val, lv,
4931-
e_ty).bcx;
4936+
bcx = move_val_if_temp(lv.res.bcx, INIT, dst_res.val,
4937+
lv, e_ty);
49324938
break;
49334939
}
49344940
}
49354941
if !expr_provided {
49364942
let src_res = GEP_tup_like(bcx, t, base_val, [0, i]);
49374943
src_res =
49384944
rslt(src_res.bcx, load_if_immediate(bcx, src_res.val, e_ty));
4939-
bcx =
4940-
copy_val(src_res.bcx, INIT, dst_res.val, src_res.val,
4941-
e_ty).bcx;
4945+
bcx = copy_val(src_res.bcx, INIT, dst_res.val, src_res.val, e_ty);
49424946
}
49434947
i += 1;
49444948
}
@@ -5023,10 +5027,9 @@ fn trans_expr_out(cx: &@block_ctxt, e: &@ast::expr, output: out_method) ->
50235027
let t = ty::expr_ty(bcx_tcx(cx), src);
50245028
// FIXME: calculate copy init-ness in typestate.
50255029

5026-
let move_res =
5027-
move_val(rhs_res.res.bcx, DROP_EXISTING, lhs_res.res.val, rhs_res,
5028-
t);
5029-
ret rslt(move_res.bcx, C_nil());
5030+
let bcx = move_val(rhs_res.res.bcx, DROP_EXISTING, lhs_res.res.val,
5031+
rhs_res, t);
5032+
ret rslt(bcx, C_nil());
50305033
}
50315034
ast::expr_assign(dst, src) {
50325035
let lhs_res = trans_lval(cx, dst);
@@ -5035,10 +5038,9 @@ fn trans_expr_out(cx: &@block_ctxt, e: &@ast::expr, output: out_method) ->
50355038
let rhs = trans_lval(lhs_res.res.bcx, src);
50365039
let t = ty::expr_ty(bcx_tcx(cx), src);
50375040
// FIXME: calculate copy init-ness in typestate.
5038-
let copy_res =
5039-
move_val_if_temp(rhs.res.bcx, DROP_EXISTING, lhs_res.res.val, rhs,
5040-
t);
5041-
ret rslt(copy_res.bcx, C_nil());
5041+
let bcx = move_val_if_temp(rhs.res.bcx, DROP_EXISTING,
5042+
lhs_res.res.val, rhs, t);
5043+
ret rslt(bcx, C_nil());
50425044
}
50435045
ast::expr_swap(dst, src) {
50445046
let lhs_res = trans_lval(cx, dst);
@@ -5083,10 +5085,9 @@ fn trans_expr_out(cx: &@block_ctxt, e: &@ast::expr, output: out_method) ->
50835085
trans_eager_binop(rhs_res.bcx, op, lhs_val, t, rhs_res.val, t);
50845086
// FIXME: calculate copy init-ness in typestate.
50855087
// This is always a temporary, so can always be safely moved
5086-
let move_res =
5087-
move_val(v.bcx, DROP_EXISTING, lhs_res.res.val,
5088-
lval_val(v.bcx, v.val), t);
5089-
ret rslt(move_res.bcx, C_nil());
5088+
let bcx = move_val(v.bcx, DROP_EXISTING, lhs_res.res.val,
5089+
lval_val(v.bcx, v.val), t);
5090+
ret rslt(bcx, C_nil());
50905091
}
50915092
ast::expr_bind(f, args) { ret trans_bind(cx, f, args, e.id); }
50925093
ast::expr_call(f, args) {
@@ -5425,9 +5426,9 @@ fn trans_ret(cx: &@block_ctxt, e: &option::t<@ast::expr>) -> result {
54255426
_ { false }
54265427
};
54275428
if is_local {
5428-
bcx = move_val(bcx, INIT, cx.fcx.llretptr, lv, t).bcx;
5429+
bcx = move_val(bcx, INIT, cx.fcx.llretptr, lv, t);
54295430
} else {
5430-
bcx = move_val_if_temp(bcx, INIT, cx.fcx.llretptr, lv, t).bcx;
5431+
bcx = move_val_if_temp(bcx, INIT, cx.fcx.llretptr, lv, t);
54315432
}
54325433
}
54335434
_ {
@@ -5476,11 +5477,11 @@ fn init_local(bcx: @block_ctxt, local: &@ast::local) -> result {
54765477
// the value.
54775478
ty = node_id_type(bcx_ccx(bcx), init.expr.id);
54785479
let sub = trans_lval(bcx, init.expr);
5479-
bcx = move_val_if_temp(sub.res.bcx, INIT, llptr, sub, ty).bcx;
5480+
bcx = move_val_if_temp(sub.res.bcx, INIT, llptr, sub, ty);
54805481
}
54815482
ast::init_move. {
54825483
let sub = trans_lval(bcx, init.expr);
5483-
bcx = move_val(sub.res.bcx, INIT, llptr, sub, ty).bcx;
5484+
bcx = move_val(sub.res.bcx, INIT, llptr, sub, ty);
54845485
}
54855486
}
54865487
}
@@ -5750,7 +5751,7 @@ fn trans_block(cx: &@block_ctxt, b: &ast::blk, output: &out_method) ->
57505751
// The output method is to save the value at target,
57515752
// and we didn't pass it to the recursive trans_expr
57525753
// call.
5753-
bcx = move_val_if_temp(bcx, INIT, target, lv, r_ty).bcx;
5754+
bcx = move_val_if_temp(bcx, INIT, target, lv, r_ty);
57545755
r = rslt(bcx, C_nil());
57555756
}
57565757
return. { }
@@ -6134,7 +6135,7 @@ fn trans_res_ctor(cx: @local_ctxt, sp: &span, dtor: &ast::_fn,
61346135

61356136
let dst = GEP_tup_like(bcx, tup_t, llretptr, [0, 1]);
61366137
bcx = dst.bcx;
6137-
bcx = copy_val(bcx, INIT, dst.val, arg, arg_t).bcx;
6138+
bcx = copy_val(bcx, INIT, dst.val, arg, arg_t);
61386139
let flag = GEP_tup_like(bcx, tup_t, llretptr, [0, 0]);
61396140
bcx = flag.bcx;
61406141
bcx.build.Store(C_int(1), flag.val);
@@ -6223,8 +6224,7 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
62236224
ty::type_has_dynamic_size(cx.ccx.tcx, arg_ty) {
62246225
llargval = llargptr;
62256226
} else { llargval = bcx.build.Load(llargptr); }
6226-
rslt = copy_val(bcx, INIT, lldestptr, llargval, arg_ty);
6227-
bcx = rslt.bcx;
6227+
bcx = copy_val(bcx, INIT, lldestptr, llargval, arg_ty);
62286228
i += 1u;
62296229
}
62306230
bcx = trans_block_cleanups(bcx, find_scope_cx(bcx));

0 commit comments

Comments
 (0)