提交 ce9e0fc9 编写于 作者: P Patrick Walton

Revert "Get rid of 'overwrite' destination kind"

This reverts commit 6e652588.
上级 11e407aa
......@@ -2112,7 +2112,6 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
ty_to_str(tcx, t));
}
// FIXME[DPS] rename to store_temp_expr
fn move_val_if_temp(cx: @block_ctxt, action: copy_action, dst: ValueRef,
src: lval_result, t: ty::t) -> @block_ctxt {
// Lvals in memory are not temporaries. Copy them.
......@@ -2214,7 +2213,7 @@ fn trans_unary(bcx: @block_ctxt, op: ast::unop, e: @ast::expr,
let llety = T_ptr(type_of(ccx, e_sp, e_ty));
body = PointerCast(bcx, body, llety);
}
bcx = trans_expr_save_in(bcx, e, body);
bcx = trans_expr_save_in(bcx, e, body, INIT);
revoke_clean(bcx, box);
ret store_in_dest(bcx, box, dest);
}
......@@ -2256,7 +2255,8 @@ fn trans_expr_fn(bcx: @block_ctxt, f: ast::_fn, sp: span,
trans_closure(sub_cx, sp, f, llfn, none, [], id, {|_fcx|});
}
};
fill_fn_pair(bcx, get_dest_addr(dest), llfn, env);
let {bcx, val: addr} = get_dest_addr(bcx, dest);
fill_fn_pair(bcx, addr, llfn, env);
ret bcx;
}
......@@ -2357,18 +2357,19 @@ fn trans_assign_op(bcx: @block_ctxt, op: ast::binop, dst: @ast::expr,
}
_ { }
}
let {bcx, val: rhs_val} = trans_expr(lhs_res.bcx, src);
let rhs_res = trans_expr(lhs_res.bcx, src);
if ty::type_is_sequence(tcx, t) {
alt op {
ast::add. {
ret tvec::trans_append(bcx, t, lhs_res.val, rhs_val);
ret tvec::trans_append(rhs_res.bcx, t, lhs_res.val,
rhs_res.val);
}
_ { }
}
}
ret trans_eager_binop(bcx, op, Load(bcx, lhs_res.val), t, rhs_val, t,
save_in(lhs_res.val));
let lhs_val = load_if_immediate(rhs_res.bcx, lhs_res.val, t);
ret trans_eager_binop(rhs_res.bcx, op, lhs_val, t, rhs_res.val, t,
overwrite(lhs_res.val, t));
}
fn autoderef(cx: @block_ctxt, v: ValueRef, t: ty::t) -> result_t {
......@@ -2484,6 +2485,7 @@ fn join_branches(parent_cx: @block_ctxt, ins: [result]) -> @block_ctxt {
by_val(@mutable ValueRef);
by_ref(@mutable ValueRef);
save_in(ValueRef);
overwrite(ValueRef, ty::t);
ignore;
}
......@@ -2536,12 +2538,19 @@ fn store_in_dest(bcx: @block_ctxt, val: ValueRef, dest: dest) -> @block_ctxt {
ignore. {}
by_val(cell) { *cell = val; }
save_in(addr) { Store(bcx, val, addr); }
overwrite(addr, tp) {
bcx = drop_ty(bcx, addr, tp);
Store(bcx, val, addr);
}
}
ret bcx;
}
fn get_dest_addr(dest: dest) -> ValueRef {
alt dest { save_in(a) { a } }
fn get_dest_addr(bcx: @block_ctxt, dest: dest) -> result {
alt dest {
save_in(a) { rslt(bcx, a) }
overwrite(a, t) { rslt(drop_ty(bcx, a, t), a) }
}
}
// Wrapper through which legacy non-DPS code can use DPS functions
......@@ -2724,7 +2733,7 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
bcx = bound.bcx;
alt bv {
env_expr(e) {
bcx = trans_expr_save_in(bcx, e, bound.val);
bcx = trans_expr_save_in(bcx, e, bound.val, INIT);
add_clean_temp_mem(bcx, bound.val, bound_tys[i]);
temp_cleanups += [bound.val];
}
......@@ -3689,7 +3698,8 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
let lv = lval_maybe_callee_to_lval(f_res, pair_ty);
bcx = lv.bcx;
// FIXME[DPS] factor this out
ret memmove_ty(bcx, get_dest_addr(dest), lv.val, pair_ty);
let {bcx, val: addr} = get_dest_addr(bcx, dest);
ret memmove_ty(bcx, addr, lv.val, pair_ty);
}
let closure = alt f_res.env {
null_env. { none }
......@@ -3726,7 +3736,8 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
closure.ptrty, ty_param_count, target_res);
// Fill the function pair
fill_fn_pair(bcx, get_dest_addr(dest), llthunk.val, closure.ptr);
let {bcx, val: addr} = get_dest_addr(bcx, dest);
fill_fn_pair(bcx, addr, llthunk.val, closure.ptr);
ret bcx;
}
......@@ -3834,7 +3845,7 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef,
} else { alloca(cx, llretty) }
}
save_in(dst) { dst }
by_val(_) { alloca(cx, llretty) }
overwrite(_, _) | by_val(_) { alloca(cx, llretty) }
by_ref(_) { dest_ref = true; alloca(cx, T_ptr(llretty)) }
};
// FIXME[DSP] does this always hold?
......@@ -3959,6 +3970,10 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
}
}
save_in(_) { } // Already saved by callee
overwrite(a, t) {
bcx = drop_ty(bcx, a, t);
bcx = memmove_ty(bcx, a, llretslot, ret_ty);
}
by_ref(cell) | by_val(cell) {
*cell = Load(bcx, llretslot);
}
......@@ -4152,23 +4167,34 @@ fn trans_landing_pad(bcx: @block_ctxt,
fn trans_tup(bcx: @block_ctxt, elts: [@ast::expr], id: ast::node_id,
dest: dest) -> @block_ctxt {
let t = node_id_type(bcx.fcx.lcx.ccx, id);
let addr = alt dest {
let (addr, overwrite) = alt dest {
ignore. {
for ex in elts { bcx = trans_expr_dps(bcx, ex, ignore); }
ret bcx;
}
save_in(pos) { pos }
save_in(pos) { (pos, none) }
overwrite(pos, _) {
let scratch = alloca(bcx, llvm::LLVMGetElementType(val_ty(pos)));
(scratch, some(pos))
}
};
let temp_cleanups = [], i = 0;
for e in elts {
let dst = GEP_tup_like_1(bcx, t, addr, [0, i]);
let e_ty = ty::expr_ty(bcx_tcx(bcx), e);
bcx = trans_expr_save_in(dst.bcx, e, dst.val);
bcx = trans_expr_save_in(dst.bcx, e, dst.val, INIT);
add_clean_temp_mem(bcx, dst.val, e_ty);
temp_cleanups += [dst.val];
i += 1;
}
for cleanup in temp_cleanups { revoke_clean(bcx, cleanup); }
alt overwrite {
some(pos) {
bcx = drop_ty(bcx, pos, t);
bcx = memmove_ty(bcx, pos, addr, t);
}
none. {}
}
ret bcx;
}
......@@ -4176,14 +4202,20 @@ fn trans_rec(bcx: @block_ctxt, fields: [ast::field],
base: option::t<@ast::expr>, id: ast::node_id,
dest: dest) -> @block_ctxt {
let t = node_id_type(bcx_ccx(bcx), id);
let addr = alt dest {
let (addr, overwrite) = alt dest {
ignore. {
for fld in fields {
bcx = trans_expr_dps(bcx, fld.node.expr, ignore);
}
ret bcx;
}
save_in(pos) { pos }
save_in(pos) { (pos, none) }
// The expressions that populate the fields might still use the old
// record, so we build the new on in a scratch area
overwrite(pos, _) {
let scratch = alloca(bcx, llvm::LLVMGetElementType(val_ty(pos)));
(scratch, some(pos))
}
};
let base_val = alt base {
......@@ -4202,7 +4234,7 @@ fn trans_rec(bcx: @block_ctxt, fields: [ast::field],
bcx = dst.bcx;
alt vec::find({|f| str::eq(f.node.ident, tf.ident)}, fields) {
some(f) {
bcx = trans_expr_save_in(bcx, f.node.expr, dst.val);
bcx = trans_expr_save_in(bcx, f.node.expr, dst.val, INIT);
}
none. {
let base = GEP_tup_like_1(bcx, t, base_val, [0, i]);
......@@ -4217,6 +4249,13 @@ fn trans_rec(bcx: @block_ctxt, fields: [ast::field],
// Now revoke the cleanups as we pass responsibility for the data
// structure on to the caller
for cleanup in temp_cleanups { revoke_clean(bcx, cleanup); }
alt overwrite {
some(pos) {
bcx = drop_ty(bcx, pos, t);
bcx = memmove_ty(bcx, pos, addr, t);
}
none. {}
}
ret bcx;
}
......@@ -4235,37 +4274,19 @@ fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result {
}
}
fn trans_expr_save_in(bcx: @block_ctxt, e: @ast::expr, dest: ValueRef)
-> @block_ctxt {
fn trans_expr_save_in(bcx: @block_ctxt, e: @ast::expr, dest: ValueRef,
kind: copy_action) -> @block_ctxt {
let tcx = bcx_tcx(bcx), t = ty::expr_ty(tcx, e);
let dst = if ty::type_is_bot(tcx, t) || ty::type_is_nil(tcx, t) {
ignore
} else { save_in(dest) };
ret trans_expr_dps(bcx, e, dst);
}
fn trans_temp_expr(bcx: @block_ctxt, e: @ast::expr) -> lval_result {
if expr_is_lval(bcx_tcx(bcx), e) {
ret trans_lval(bcx, e);
} else if kind == INIT {
save_in(dest)
} else {
let tcx = bcx_tcx(bcx);
let ty = ty::expr_ty(tcx, e);
if ty::type_is_nil(tcx, ty) || ty::type_is_bot(tcx, ty) {
bcx = trans_expr_dps(bcx, e, ignore);
ret {bcx: bcx, val: C_nil(), is_mem: false};
} else if type_is_immediate(bcx_ccx(bcx), ty) {
let cell = empty_dest_cell();
bcx = trans_expr_dps(bcx, e, by_val(cell));
ret {bcx: bcx, val: *cell, is_mem: false};
} else {
let {bcx, val: scratch} = alloc_ty(bcx, ty);
bcx = trans_expr_dps(bcx, e, save_in(scratch));
ret {bcx: bcx, val: scratch, is_mem: false};
}
}
overwrite(dest, t)
};
ret trans_expr_dps(bcx, e, dst);
}
// FIXME[DPS] supersede by trans_temp_expr, get rid of by_ref dests
fn trans_expr_by_ref(bcx: @block_ctxt, e: @ast::expr) -> result {
let cell = empty_dest_cell();
bcx = trans_expr_dps(bcx, e, by_ref(cell));
......@@ -4409,20 +4430,22 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
}
ast::expr_assign(dst, src) {
assert dest == ignore;
let src_r = trans_temp_expr(bcx, src);
let {bcx, val: addr, is_mem} = trans_lval(src_r.bcx, dst);
let {bcx, val: lhs_addr, is_mem} = trans_lval(bcx, dst);
assert is_mem;
ret move_val_if_temp(bcx, DROP_EXISTING, addr, src_r,
ty::expr_ty(bcx_tcx(bcx), src));
ret trans_expr_save_in(bcx, src, lhs_addr, DROP_EXISTING);
}
ast::expr_move(dst, src) {
// FIXME: calculate copy init-ness in typestate.
assert dest == ignore;
let src_r = trans_temp_expr(bcx, src);
let {bcx, val: addr, is_mem} = trans_lval(src_r.bcx, dst);
let {bcx, val: addr, is_mem} = trans_lval(bcx, dst);
assert is_mem;
ret move_val(bcx, DROP_EXISTING, addr, src_r,
ty::expr_ty(bcx_tcx(bcx), src));
// FIXME: calculate copy init-ness in typestate.
if expr_is_lval(tcx, src) {
ret trans_expr_save_in(bcx, src, addr, DROP_EXISTING);
} else {
let srclv = trans_lval(bcx, src);
let t = ty::expr_ty(tcx, src);
ret move_val(srclv.bcx, DROP_EXISTING, addr, srclv, t);
}
}
ast::expr_swap(dst, src) {
assert dest == ignore;
......@@ -4469,6 +4492,9 @@ fn lval_to_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
*cell = val;
}
save_in(loc) { bcx = move_val_if_temp(bcx, INIT, loc, lv, ty); }
overwrite(loc, _) {
bcx = move_val_if_temp(bcx, DROP_EXISTING, loc, lv, ty);
}
ignore. {}
}
ret bcx;
......@@ -4720,7 +4746,7 @@ fn trans_ret(bcx: @block_ctxt, e: option::t<@ast::expr>) -> @block_ctxt {
Store(cx, val, bcx.fcx.llretptr);
bcx = cx;
} else {
bcx = trans_expr_save_in(bcx, x, bcx.fcx.llretptr);
bcx = trans_expr_save_in(bcx, x, bcx.fcx.llretptr, INIT);
}
}
_ {}
......@@ -4758,7 +4784,7 @@ fn init_local(bcx: @block_ctxt, local: @ast::local) -> @block_ctxt {
some(init) {
if init.op == ast::init_assign ||
!expr_is_lval(bcx_tcx(bcx), init.expr) {
bcx = trans_expr_save_in(bcx, init.expr, llptr);
bcx = trans_expr_save_in(bcx, init.expr, llptr, INIT);
} else { // This is a move from an lval, must perform an actual move
let sub = trans_lval(bcx, init.expr);
bcx = move_val(sub.bcx, INIT, llptr, sub, ty);
......
......@@ -378,7 +378,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
revoke_clean(bcx, box);
box = PointerCast(bcx, box, llbox_ty);
}
let pair = trans::get_dest_addr(dest);
let {bcx, val: pair} = trans::get_dest_addr(bcx, dest);
let pair_vtbl = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
Store(bcx, vtbl, pair_vtbl);
let pair_box = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_box)]);
......
......@@ -29,7 +29,7 @@ fn trans_uniq(bcx: @block_ctxt, contents: @ast::expr,
check type_is_unique_box(bcx, uniq_ty);
let {bcx, val: llptr} = alloc_uniq(bcx, uniq_ty);
add_clean_free(bcx, llptr, true);
bcx = trans::trans_expr_save_in(bcx, contents, llptr);
bcx = trans::trans_expr_save_in(bcx, contents, llptr, INIT);
revoke_clean(bcx, llptr);
ret trans::store_in_dest(bcx, llptr, dest);
}
......
......@@ -124,13 +124,17 @@ fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id,
let lleltptr = if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
InBoundsGEP(bcx, dataptr, [Mul(bcx, C_uint(i), llunitsz)])
} else { InBoundsGEP(bcx, dataptr, [C_uint(i)]) };
bcx = trans::trans_expr_save_in(bcx, e, lleltptr);
bcx = trans::trans_expr_save_in(bcx, e, lleltptr, INIT);
add_clean_temp_mem(bcx, lleltptr, unit_ty);
temp_cleanups += [lleltptr];
i += 1u;
}
for clean in temp_cleanups { revoke_clean(bcx, clean); }
Store(bcx, vptr, trans::get_dest_addr(dest));
let vptrptr = alt dest {
trans::save_in(a) { a }
trans::overwrite(a, t) { bcx = trans::drop_ty(bcx, a, t); a }
};
Store(bcx, vptr, vptrptr);
ret bcx;
}
......@@ -143,7 +147,11 @@ fn trans_str(bcx: @block_ctxt, s: str, dest: dest) -> @block_ctxt {
let bcx =
call_memmove(bcx, get_dataptr_simple(bcx, sptr, T_i8()), llcstr,
C_uint(veclen)).bcx;
Store(bcx, sptr, trans::get_dest_addr(dest));
let sptrptr = alt dest {
trans::save_in(a) { a }
trans::overwrite(a, t) { bcx = trans::drop_ty(bcx, a, t); a }
};
Store(bcx, sptr, sptrptr);
ret bcx;
}
......@@ -258,7 +266,13 @@ fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
let bcx = iter_vec_raw(bcx, lhsptr, vec_ty, lhs_fill, copy_fn);
bcx = iter_vec_raw(bcx, rhsptr, vec_ty, rhs_fill, copy_fn);
Store(bcx, new_vec_ptr, trans::get_dest_addr(dest));
alt dest {
trans::save_in(a) { Store(bcx, new_vec_ptr, a); }
trans::overwrite(a, t) {
bcx = trans::drop_ty(bcx, a, t);
Store(bcx, new_vec_ptr, a);
}
}
ret bcx;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册