Skip to content

Commit 549c074

Browse files
committed
---
yaml --- r: 5669 b: refs/heads/master c: 276dfc6 h: refs/heads/master i: 5667: 35598c0 v: v3
1 parent ac592ec commit 549c074

File tree

2 files changed

+57
-58
lines changed

2 files changed

+57
-58
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: ce9e0fc94f4a74594e7b342d128b3713b53ef0d7
2+
refs/heads/master: 276dfc6133f3c7d3b40778789f72379800f62176

trunk/src/comp/middle/trans.rs

Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2470,7 +2470,7 @@ fn trans_binary(cx: @block_ctxt, op: ast::binop, a: @ast::expr, b: @ast::expr,
24702470
}
24712471
}
24722472

2473-
// FIXME[DPS] remove once all uses have been converted to join_returns
2473+
// FIXME remove once all uses have been converted to join_returns
24742474
fn join_branches(parent_cx: @block_ctxt, ins: [result]) -> @block_ctxt {
24752475
let out = new_sub_block_ctxt(parent_cx, "join");
24762476
let branched = false;
@@ -2952,7 +2952,8 @@ fn trans_for_each(cx: @block_ctxt, local: @ast::local, seq: @ast::expr,
29522952
ast::expr_call(f, args) {
29532953
let pair =
29542954
create_real_fn_pair(cx, iter_body_llty, lliterbody, llenv.ptr);
2955-
ret trans_call(cx, f, some(pair), args, seq.id, ignore);
2955+
let r = trans_call(cx, f, some(pair), args, seq.id);
2956+
ret r.res.bcx;
29562957
}
29572958
}
29582959
}
@@ -3299,7 +3300,6 @@ fn expr_is_lval(tcx: ty::ctxt, e: @ast::expr) -> bool {
32993300
// The additional bool returned indicates whether it's mem (that is
33003301
// represented as an alloca or heap, hence needs a 'load' to be used as an
33013302
// immediate).
3302-
// FIXME[DPS] only allow this to be called on actual lvals
33033303
fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
33043304
alt e.node {
33053305
ast::expr_path(p) {
@@ -3340,17 +3340,10 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
33403340
ret lval_mem(sub.bcx, val);
33413341
}
33423342
ast::expr_call(f, args) {
3343-
// A by-ref returning function
3344-
if expr_is_lval(bcx_tcx(cx), e) {
3345-
let cell = empty_dest_cell();
3346-
let bcx = trans_call(cx, f, none, args, e.id, by_ref(cell));
3347-
ret lval_mem(bcx, *cell);
3348-
} else { // By-value return
3349-
let {bcx, val} = dps_to_result(cx, {|bcx, dest|
3350-
trans_call(bcx, f, none, args, e.id, dest) },
3351-
ty::expr_ty(bcx_tcx(cx), e));
3352-
ret lval_val(bcx, val);
3353-
}
3343+
let {res: {bcx, val}, by_ref} =
3344+
trans_call(cx, f, none, args, e.id);
3345+
if by_ref { ret lval_mem(bcx, val); }
3346+
else { ret lval_val(bcx, val); }
33543347
}
33553348
_ {
33563349
let res = trans_expr(cx, e);
@@ -3804,8 +3797,7 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty0: TypeRef,
38043797
// - trans_args
38053798
fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef,
38063799
gen: option::t<generic_info>,
3807-
lliterbody: option::t<ValueRef>, es: [@ast::expr], fn_ty: ty::t,
3808-
dest: dest)
3800+
lliterbody: option::t<ValueRef>, es: [@ast::expr], fn_ty: ty::t)
38093801
-> {bcx: @block_ctxt,
38103802
outer_cx: @block_ctxt,
38113803
args: [ValueRef],
@@ -3821,9 +3813,9 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef,
38213813

38223814
let ccx = bcx_ccx(cx);
38233815
let tcx = ccx.tcx;
3824-
let bcx = cx;
3816+
let bcx: @block_ctxt = cx;
38253817
let ret_style = ty::ty_fn_ret_style(tcx, fn_ty);
3826-
let ret_ref = ast_util::ret_by_ref(ret_style);
3818+
let by_ref = ast_util::ret_by_ref(ret_style);
38273819

38283820
let retty = ty::ty_fn_ret(tcx, fn_ty), full_retty = retty;
38293821
alt gen {
@@ -3836,21 +3828,13 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef,
38363828
_ { }
38373829
}
38383830
// Arg 0: Output pointer.
3839-
let llretty = type_of_or_i8(bcx, full_retty);
3840-
let dest_ref = false;
3841-
let llretslot = alt dest {
3842-
ignore. {
3843-
if ty::type_is_nil(tcx, full_retty) || !option::is_none(lliterbody) {
3844-
llvm::LLVMGetUndef(T_ptr(llretty))
3845-
} else { alloca(cx, llretty) }
3846-
}
3847-
save_in(dst) { dst }
3848-
overwrite(_, _) | by_val(_) { alloca(cx, llretty) }
3849-
by_ref(_) { dest_ref = true; alloca(cx, T_ptr(llretty)) }
3850-
};
3851-
// FIXME[DSP] does this always hold?
3852-
assert dest_ref == ret_ref;
3853-
3831+
let llretslot_res = if ty::type_is_nil(tcx, retty) {
3832+
rslt(cx, llvm::LLVMGetUndef(T_ptr(T_nil())))
3833+
} else if by_ref {
3834+
rslt(cx, alloca(cx, T_ptr(type_of_or_i8(bcx, full_retty))))
3835+
} else { alloc_ty(bcx, full_retty) };
3836+
bcx = llretslot_res.bcx;
3837+
let llretslot = llretslot_res.val;
38543838
if ty::type_contains_params(tcx, retty) {
38553839
// It's possible that the callee has some generic-ness somewhere in
38563840
// its return value -- say a method signature within an obj or a fn
@@ -3859,7 +3843,7 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef,
38593843
// view, for the sake of making a type-compatible call.
38603844
check non_ty_var(ccx, retty);
38613845
let llretty = T_ptr(type_of_inner(ccx, bcx.sp, retty));
3862-
if ret_ref { llretty = T_ptr(llretty); }
3846+
if by_ref { llretty = T_ptr(llretty); }
38633847
llargs += [PointerCast(cx, llretslot, llretty)];
38643848
} else { llargs += [llretslot]; }
38653849

@@ -3915,17 +3899,18 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef,
39153899

39163900
fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
39173901
lliterbody: option::t<ValueRef>, args: [@ast::expr],
3918-
id: ast::node_id, dest: dest) -> @block_ctxt {
3902+
id: ast::node_id) -> {res: result, by_ref: bool} {
39193903
// NB: 'f' isn't necessarily a function; it might be an entire self-call
39203904
// expression because of the hack that allows us to process self-calls
39213905
// with trans_call.
39223906
let tcx = bcx_tcx(in_cx);
39233907
let fn_expr_ty = ty::expr_ty(tcx, f);
39243908

39253909
if check type_is_native_fn_on_c_stack(tcx, fn_expr_ty) {
3926-
ret trans_c_stack_native_call(in_cx, f, args, dest);
3910+
ret trans_c_stack_native_call(in_cx, f, args);
39273911
}
39283912

3913+
let by_ref = ast_util::ret_by_ref(ty::ty_fn_ret_style(tcx, fn_expr_ty));
39293914
let cx = new_scope_block_ctxt(in_cx, "call");
39303915
let f_res = trans_callee(cx, f);
39313916
let bcx = f_res.bcx;
@@ -3951,49 +3936,65 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
39513936
let ret_ty = ty::node_id_to_type(tcx, id);
39523937
let args_res =
39533938
trans_args(bcx, in_cx, llenv, f_res.generic, lliterbody, args,
3954-
fn_expr_ty, dest);
3939+
fn_expr_ty);
39553940
Br(args_res.outer_cx, cx.llbb);
39563941
bcx = args_res.bcx;
39573942
let llargs = args_res.args;
39583943
let llretslot = args_res.retslot;
39593944

3945+
/*
3946+
log_err "calling: " + val_str(bcx_ccx(cx).tn, faddr);
3947+
3948+
for arg: ValueRef in llargs {
3949+
log_err "arg: " + val_str(bcx_ccx(cx).tn, arg);
3950+
}
3951+
*/
3952+
39603953
/* If the block is terminated,
39613954
then one or more of the args has
39623955
type _|_. Since that means it diverges, the code
39633956
for the call itself is unreachable. */
3957+
let retval = C_nil();
39643958
bcx = invoke_full(bcx, faddr, llargs, args_res.to_zero,
39653959
args_res.to_revoke);
3966-
alt dest {
3967-
ignore. {
3968-
if llvm::LLVMIsUndef(llretslot) != lib::llvm::True {
3969-
bcx = drop_ty(bcx, llretslot, ret_ty);
3960+
alt lliterbody {
3961+
none. {
3962+
if !ty::type_is_nil(tcx, ret_ty) {
3963+
if by_ref {
3964+
retval = Load(bcx, llretslot);
3965+
} else {
3966+
retval = load_if_immediate(bcx, llretslot, ret_ty);
3967+
// Retval doesn't correspond to anything really tangible
3968+
// in the frame, but it's a ref all the same, so we put a
3969+
// note here to drop it when we're done in this scope.
3970+
add_clean_temp(in_cx, retval, ret_ty);
3971+
}
39703972
}
39713973
}
3972-
save_in(_) { } // Already saved by callee
3973-
overwrite(a, t) {
3974-
bcx = drop_ty(bcx, a, t);
3975-
bcx = memmove_ty(bcx, a, llretslot, ret_ty);
3976-
}
3977-
by_ref(cell) | by_val(cell) {
3978-
*cell = Load(bcx, llretslot);
3974+
some(_) {
3975+
// If there was an lliterbody, it means we were calling an
3976+
// iter, and we are *not* the party using its 'output' value,
3977+
// we should ignore llretslot.
39793978
}
39803979
}
39813980
// Forget about anything we moved out.
39823981
bcx = zero_and_revoke(bcx, args_res.to_zero, args_res.to_revoke);
39833982

3984-
bcx = trans_block_cleanups(bcx, cx);
3983+
if !by_ref { bcx = trans_block_cleanups(bcx, cx); }
39853984
let next_cx = new_sub_block_ctxt(in_cx, "next");
39863985
if bcx.unreachable || ty::type_is_bot(tcx, ret_ty) {
39873986
Unreachable(next_cx);
39883987
}
39893988
Br(bcx, next_cx.llbb);
3990-
ret next_cx;
3989+
bcx = next_cx;
3990+
ret {res: rslt(bcx, retval), by_ref: by_ref};
39913991
}
39923992

39933993
// Translates a native call on the C stack. Calls into the runtime to perform
39943994
// the stack switching operation.
39953995
fn trans_c_stack_native_call(bcx: @block_ctxt, f: @ast::expr,
3996-
args: [@ast::expr], dest: dest) -> @block_ctxt {
3996+
args: [@ast::expr])
3997+
-> {res: result, by_ref: bool} {
39973998
let ccx = bcx_ccx(bcx);
39983999
let f_res = trans_callee(bcx, f);
39994000
let llfn = f_res.val; bcx = f_res.bcx;
@@ -4046,7 +4047,8 @@ fn trans_c_stack_native_call(bcx: @block_ctxt, f: @ast::expr,
40464047

40474048
// Forget about anything we moved out.
40484049
bcx = zero_and_revoke(bcx, to_zero, to_revoke);
4049-
ret store_in_dest(bcx, llretval, dest);
4050+
4051+
ret {res: rslt(bcx, llretval), by_ref: false};
40504052
}
40514053

40524054
fn zero_and_revoke(bcx: @block_ctxt,
@@ -4343,11 +4345,8 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
43434345
ast::expr_anon_obj(anon_obj) {
43444346
ret trans_anon_obj(bcx, e.span, anon_obj, e.id, dest);
43454347
}
4346-
ast::expr_call(f, args) {
4347-
ret trans_call(bcx, f, none, args, e.id, dest);
4348-
}
4349-
// FIXME[DPS] untangle non-lval fields from trans_lval
4350-
ast::expr_field(_, _) {
4348+
// FIXME[DPS] untangle non-lval calls and fields from trans_lval
4349+
ast::expr_call(_, _) | ast::expr_field(_, _) {
43514350
ret lval_to_dps(bcx, e, dest);
43524351
}
43534352

0 commit comments

Comments
 (0)