Move more non-value-returning things to trans_expr_dps.

Issue #667
This commit is contained in:
Marijn Haverbeke 2011-09-27 08:03:06 +02:00
parent b49f4689f5
commit 8ea72fae99
2 changed files with 90 additions and 87 deletions

View file

@ -2298,6 +2298,43 @@ fn trans_eager_binop(cx: @block_ctxt, op: ast::binop, lhs: ValueRef,
}
}
fn trans_assign_op(bcx: @block_ctxt, op: ast::binop, dst: @ast::expr,
src: @ast::expr) -> @block_ctxt {
let tcx = bcx_tcx(bcx);
let t = ty::expr_ty(tcx, src);
let lhs_res = trans_lval(bcx, dst);
assert (lhs_res.is_mem);
// Special case for `+= [x]`
alt ty::struct(tcx, t) {
ty::ty_vec(_) {
alt src.node {
ast::expr_vec(args, _) {
ret tvec::trans_append_literal(lhs_res.bcx,
lhs_res.val, t, args);
}
_ { }
}
}
_ { }
}
let rhs_res = trans_expr(lhs_res.bcx, src);
if ty::type_is_sequence(tcx, t) {
alt op {
ast::add. {
ret tvec::trans_append(rhs_res.bcx, t, lhs_res.val,
rhs_res.val);
}
_ { }
}
}
let lhs_val = load_if_immediate(rhs_res.bcx, lhs_res.val, t);
let v = trans_eager_binop(rhs_res.bcx, op, lhs_val, t, rhs_res.val, t);
// FIXME: calculate copy init-ness in typestate.
// This is always a temporary, so can always be safely moved
ret move_val(v.bcx, DROP_EXISTING, lhs_res.val,
lval_val(v.bcx, v.val), t);
}
fn autoderef(cx: @block_ctxt, v: ValueRef, t: ty::t) -> result_t {
let v1: ValueRef = v;
let t1: ty::t = t;
@ -2540,7 +2577,7 @@ fn trans_if(cx: @block_ctxt, cond: @ast::expr, thn: ast::blk,
}
fn trans_for(cx: @block_ctxt, local: @ast::local, seq: @ast::expr,
body: ast::blk) -> result {
body: ast::blk) -> @block_ctxt {
fn inner(bcx: @block_ctxt, local: @ast::local, curr: ValueRef, t: ty::t,
body: ast::blk, outer_next_cx: @block_ctxt) -> @block_ctxt {
let next_cx = new_sub_block_ctxt(bcx, "next");
@ -2567,7 +2604,7 @@ fn trans_for(cx: @block_ctxt, local: @ast::local, seq: @ast::expr,
tvec::iter_vec_raw(bcx, seq, seq_ty, fill,
bind inner(_, local, _, _, body, next_cx));
Br(bcx, next_cx.llbb);
ret rslt(next_cx, C_nil());
ret next_cx;
}
@ -2789,7 +2826,7 @@ fn load_environment(enclosing_cx: @block_ctxt, fcx: @fn_ctxt, envty: ty::t,
}
fn trans_for_each(cx: @block_ctxt, local: @ast::local, seq: @ast::expr,
body: ast::blk) -> result {
body: ast::blk) -> @block_ctxt {
/*
* The translation is a little .. complex here. Code like:
*
@ -2865,12 +2902,13 @@ fn trans_for_each(cx: @block_ctxt, local: @ast::local, seq: @ast::expr,
let pair =
create_real_fn_pair(cx, iter_body_llty, lliterbody, llenv.ptr);
let r = trans_call(cx, f, some(pair), args, seq.id);
ret rslt(r.res.bcx, C_nil());
ret r.res.bcx;
}
}
}
fn trans_while(cx: @block_ctxt, cond: @ast::expr, body: ast::blk) -> result {
fn trans_while(cx: @block_ctxt, cond: @ast::expr, body: ast::blk)
-> @block_ctxt {
let next_cx = new_sub_block_ctxt(cx, "while next");
let cond_cx =
new_loop_scope_block_ctxt(cx, option::none::<@block_ctxt>, next_cx,
@ -2882,11 +2920,11 @@ fn trans_while(cx: @block_ctxt, cond: @ast::expr, body: ast::blk) -> result {
let cond_bcx = trans_block_cleanups(cond_res.bcx, cond_cx);
CondBr(cond_bcx, cond_res.val, body_cx.llbb, next_cx.llbb);
Br(cx, cond_cx.llbb);
ret rslt(next_cx, C_nil());
ret next_cx;
}
fn trans_do_while(cx: @block_ctxt, body: ast::blk, cond: @ast::expr) ->
result {
@block_ctxt {
let next_cx = new_sub_block_ctxt(cx, "next");
let body_cx =
new_loop_scope_block_ctxt(cx, option::none::<@block_ctxt>, next_cx,
@ -2895,7 +2933,7 @@ fn trans_do_while(cx: @block_ctxt, body: ast::blk, cond: @ast::expr) ->
let cond_res = trans_expr(body_res.bcx, cond);
CondBr(cond_res.bcx, cond_res.val, body_cx.llbb, next_cx.llbb);
Br(cx, body_cx.llbb);
ret rslt(next_cx, body_res.val);
ret next_cx;
}
type generic_info =
@ -4093,12 +4131,6 @@ fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result {
alt e.node {
ast::expr_lit(lit) { ret trans_lit(cx, *lit); }
ast::expr_binary(op, x, y) { ret trans_binary(cx, op, x, y); }
ast::expr_for(decl, seq, body) { ret trans_for(cx, decl, seq, body); }
ast::expr_for_each(decl, seq, body) {
ret trans_for_each(cx, decl, seq, body);
}
ast::expr_while(cond, body) { ret trans_while(cx, cond, body); }
ast::expr_do_while(body, cond) { ret trans_do_while(cx, body, cond); }
ast::expr_fn(f) {
let ccx = bcx_ccx(cx);
let fty = node_id_type(ccx, e.id);
@ -4152,77 +4184,6 @@ fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result {
t);
ret rslt(bcx, C_nil());
}
ast::expr_assign(dst, src) {
let lhs_res = trans_lval(cx, dst);
assert (lhs_res.is_mem);
// FIXME Fill in lhs_res.bcx.sp
let rhs = trans_lval(lhs_res.bcx, src);
let t = ty::expr_ty(bcx_tcx(cx), src);
// FIXME: calculate copy init-ness in typestate.
let bcx =
move_val_if_temp(rhs.bcx, DROP_EXISTING, lhs_res.val, rhs,
t);
ret rslt(bcx, C_nil());
}
ast::expr_swap(dst, src) {
let lhs_res = trans_lval(cx, dst);
assert (lhs_res.is_mem);
// FIXME Fill in lhs_res.bcx.sp
let rhs_res = trans_lval(lhs_res.bcx, src);
let t = ty::expr_ty(bcx_tcx(cx), src);
let {bcx: bcx, val: tmp_alloc} = alloc_ty(rhs_res.bcx, t);
// Swap through a temporary.
bcx = move_val(bcx, INIT, tmp_alloc, lhs_res, t);
bcx = move_val(bcx, INIT, lhs_res.val, rhs_res, t);
bcx =
move_val(bcx, INIT, rhs_res.val, lval_mem(bcx, tmp_alloc), t);
ret rslt(bcx, C_nil());
}
ast::expr_assign_op(op, dst, src) {
let tcx = bcx_tcx(cx);
let t = ty::expr_ty(tcx, src);
let lhs_res = trans_lval(cx, dst);
assert (lhs_res.is_mem);
// Special case for `+= [x]`
alt ty::struct(tcx, t) {
ty::ty_vec(_) {
alt src.node {
ast::expr_vec(args, _) {
let bcx =
tvec::trans_append_literal(lhs_res.bcx,
lhs_res.val, t, args);
ret rslt(bcx, C_nil());
}
_ { }
}
}
_ { }
}
// FIXME Fill in lhs_res.bcx.sp
let rhs_res = trans_expr(lhs_res.bcx, src);
if ty::type_is_sequence(tcx, t) {
alt op {
ast::add. {
ret tvec::trans_append(rhs_res.bcx, t, lhs_res.val,
rhs_res.val);
}
_ { }
}
}
let lhs_val = load_if_immediate(rhs_res.bcx, lhs_res.val, t);
let v =
trans_eager_binop(rhs_res.bcx, op, lhs_val, t, rhs_res.val, t);
// FIXME: calculate copy init-ness in typestate.
// This is always a temporary, so can always be safely moved
let bcx =
move_val(v.bcx, DROP_EXISTING, lhs_res.val,
lval_val(v.bcx, v.val), t);
ret rslt(bcx, C_nil());
}
ast::expr_bind(f, args) { ret trans_bind(cx, f, args, e.id); }
ast::expr_cast(val, _) { ret trans_cast(cx, val, e.id); }
ast::expr_vec(args, _) { ret tvec::trans_vec(cx, args, e.id); }
@ -4360,6 +4321,48 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
ret join_branches(bcx, [rslt(check_cx, C_nil()),
rslt(else_cx, C_nil())]);
}
ast::expr_for(decl, seq, body) {
assert dest == ignore;
ret trans_for(bcx, decl, seq, body);
}
ast::expr_for_each(decl, seq, body) {
assert dest == ignore;
ret trans_for_each(bcx, decl, seq, body);
}
ast::expr_while(cond, body) {
assert dest == ignore;
ret trans_while(bcx, cond, body);
}
ast::expr_do_while(body, cond) {
assert dest == ignore;
ret trans_do_while(bcx, body, cond);
}
ast::expr_assign(dst, src) {
assert dest == ignore;
let lhs_res = trans_lval(bcx, dst);
assert (lhs_res.is_mem);
let rhs = trans_lval(lhs_res.bcx, src);
let t = ty::expr_ty(bcx_tcx(bcx), src);
// FIXME: calculate copy init-ness in typestate.
ret move_val_if_temp(rhs.bcx, DROP_EXISTING, lhs_res.val,
rhs, t);
}
ast::expr_swap(dst, src) {
assert dest == ignore;
let lhs_res = trans_lval(bcx, dst);
assert (lhs_res.is_mem);
let rhs_res = trans_lval(lhs_res.bcx, src);
let t = ty::expr_ty(bcx_tcx(bcx), src);
let {bcx: bcx, val: tmp_alloc} = alloc_ty(rhs_res.bcx, t);
// Swap through a temporary.
bcx = move_val(bcx, INIT, tmp_alloc, lhs_res, t);
bcx = move_val(bcx, INIT, lhs_res.val, rhs_res, t);
ret move_val(bcx, INIT, rhs_res.val, lval_mem(bcx, tmp_alloc), t);
}
ast::expr_assign_op(op, dst, src) {
assert dest == ignore;
ret trans_assign_op(bcx, op, dst, src);
}
ast::expr_mac(_) { ret bcx_ccx(bcx).sess.bug("unexpanded macro"); }
// Convert back from result to DPS

View file

@ -141,7 +141,7 @@ fn trans_str(bcx: @block_ctxt, s: str) -> result {
}
fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
rhsptr: ValueRef) -> result {
rhsptr: ValueRef) -> @block_ctxt {
// Cast to opaque interior vector types if necessary.
let unit_ty = ty::sequence_element_type(bcx_tcx(cx), vec_ty);
let dynamic = ty::type_has_dynamic_size(bcx_tcx(cx), unit_ty);
@ -190,7 +190,7 @@ fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
write_ptr_ptr);
ret bcx;
});
ret rslt(bcx, C_nil());
ret bcx;
}
fn trans_append_literal(bcx: @block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,