rustc: Make unique pointers no longer immediates.
This commit is contained in:
parent
9946e467ff
commit
7a0c9759fe
@ -2088,12 +2088,13 @@ fn memmove_ty(cx: &@block_ctxt, dst: ValueRef, src: ValueRef, t: ty::t) ->
|
||||
let sp = cx.sp;
|
||||
let llsz = llsize_of(type_of(ccx, sp, t));
|
||||
ret call_memmove(cx, dst, src, llsz);
|
||||
} else { ret rslt(cx, Store(cx, Load(cx, src), dst)); }
|
||||
}
|
||||
else {
|
||||
let llsz = size_of(cx, t);
|
||||
ret call_memmove(llsz.bcx, dst, src, llsz.val);
|
||||
}
|
||||
|
||||
ret rslt(cx, Store(cx, Load(cx, src), dst));
|
||||
}
|
||||
|
||||
let llsz = size_of(cx, t);
|
||||
ret call_memmove(llsz.bcx, dst, src, llsz.val);
|
||||
}
|
||||
|
||||
tag copy_action { INIT; DROP_EXISTING; }
|
||||
@ -2136,17 +2137,18 @@ fn copy_val_no_check(cx: &@block_ctxt, action: copy_action, dst: ValueRef,
|
||||
if ty::type_is_scalar(ccx.tcx, t) || ty::type_is_native(ccx.tcx, t) {
|
||||
Store(cx, src, dst);
|
||||
ret cx;
|
||||
} else if ty::type_is_nil(ccx.tcx, t) || ty::type_is_bot(ccx.tcx, t) {
|
||||
ret cx;
|
||||
} else if ty::type_is_boxed(ccx.tcx, t) || ty::type_is_vec(ccx.tcx, t) {
|
||||
let bcx =
|
||||
if action == DROP_EXISTING { drop_ty(cx, dst, t) } else { cx };
|
||||
}
|
||||
if ty::type_is_nil(ccx.tcx, t) || ty::type_is_bot(ccx.tcx, t) { ret cx; }
|
||||
if ty::type_is_boxed(ccx.tcx, t) {
|
||||
let bcx = cx;
|
||||
if action == DROP_EXISTING { bcx = drop_ty(cx, dst, t); }
|
||||
Store(bcx, src, dst);
|
||||
bcx = take_ty(bcx, dst, t);
|
||||
ret bcx;
|
||||
} else if type_is_structural_or_param(ccx.tcx, t) {
|
||||
let bcx =
|
||||
if action == DROP_EXISTING { drop_ty(cx, dst, t) } else { cx };
|
||||
ret take_ty(bcx, dst, t);
|
||||
}
|
||||
if type_is_structural_or_param(ccx.tcx, t) ||
|
||||
ty::type_is_vec(ccx.tcx, t) {
|
||||
let bcx = cx;
|
||||
if action == DROP_EXISTING { bcx = drop_ty(cx, dst, t); }
|
||||
bcx = memmove_ty(bcx, dst, src, t).bcx;
|
||||
ret take_ty(bcx, dst, t);
|
||||
}
|
||||
@ -2170,7 +2172,7 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
|
||||
ret cx;
|
||||
} else if ty::type_is_nil(tcx, t) || ty::type_is_bot(tcx, t) {
|
||||
ret cx;
|
||||
} else if ty::type_is_unique(tcx, t) || ty::type_is_boxed(tcx, t) {
|
||||
} else if ty::type_is_boxed(tcx, t) {
|
||||
if src.is_mem { src_val = Load(cx, src_val); }
|
||||
if action == DROP_EXISTING { cx = drop_ty(cx, dst, t); }
|
||||
Store(cx, src_val, dst);
|
||||
@ -2179,7 +2181,8 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
|
||||
// If we're here, it must be a temporary.
|
||||
revoke_clean(cx, src_val);
|
||||
ret cx;
|
||||
} else if type_is_structural_or_param(tcx, t) {
|
||||
} else if ty::type_is_unique(tcx, t) ||
|
||||
type_is_structural_or_param(tcx, t) {
|
||||
if action == DROP_EXISTING { cx = drop_ty(cx, dst, t); }
|
||||
cx = memmove_ty(cx, dst, src_val, t).bcx;
|
||||
if src.is_mem {
|
||||
@ -3496,7 +3499,8 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: ty::t,
|
||||
if is_val { T_ptr(llout_arg_ty) } else { llout_arg_ty };
|
||||
val = PointerCast(bcx, val, ty);
|
||||
}
|
||||
if is_val && type_is_immediate(cx.ccx, e_ty) {
|
||||
if is_val && (type_is_immediate(cx.ccx, e_ty) ||
|
||||
ty::type_is_unique(cx.ccx.tcx, e_ty)) {
|
||||
val = Load(bcx, val);
|
||||
}
|
||||
llargs += [val];
|
||||
@ -3529,6 +3533,7 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: ty::t,
|
||||
type_of_fn_from_ty(bcx_ccx(bcx), sp, outgoing_fty, ty_param_count);
|
||||
lltargetfn = PointerCast(bcx, lltargetfn, T_ptr(T_ptr(lltargetty)));
|
||||
lltargetfn = Load(bcx, lltargetfn);
|
||||
|
||||
FastCall(bcx, lltargetfn, llargs);
|
||||
build_return(bcx);
|
||||
finish_fn(fcx, lltop);
|
||||
@ -3629,25 +3634,25 @@ fn trans_arg_expr(cx: &@block_ctxt, arg: &ty::arg, lldestty0: TypeRef,
|
||||
// to have type lldestty0 (the callee's expected type).
|
||||
val = llvm::LLVMGetUndef(lldestty0);
|
||||
} else if arg.mode == ty::mo_val {
|
||||
if !lv.is_mem {
|
||||
// Do nothing for temporaries, just give them to callee
|
||||
if ty::type_is_vec(ccx.tcx, e_ty) {
|
||||
let r = do_spill(bcx, Load(bcx, val), e_ty);
|
||||
bcx = r.bcx;
|
||||
let arg_copy = r.val;
|
||||
|
||||
bcx = take_ty(bcx, arg_copy, e_ty);
|
||||
val = Load(bcx, arg_copy);
|
||||
add_clean_temp(bcx, arg_copy, e_ty);
|
||||
} else if !lv.is_mem {
|
||||
// Do nothing for non-vector temporaries; just give them to the
|
||||
// callee.
|
||||
} else if type_is_structural_or_param(ccx.tcx, e_ty) {
|
||||
let dst = alloc_ty(bcx, e_ty);
|
||||
bcx = copy_val(dst.bcx, INIT, dst.val, val, e_ty);
|
||||
val = dst.val;
|
||||
add_clean_temp(bcx, val, e_ty);
|
||||
} else {
|
||||
if ty::type_is_vec(ccx.tcx, e_ty) {
|
||||
let r = do_spill(bcx, Load(bcx, val), e_ty);
|
||||
bcx = r.bcx;
|
||||
let arg_copy = r.val;
|
||||
|
||||
bcx = take_ty(bcx, arg_copy, e_ty);
|
||||
val = Load(bcx, arg_copy);
|
||||
} else {
|
||||
bcx = take_ty(bcx, val, e_ty);
|
||||
val = load_if_immediate(bcx, val, e_ty);
|
||||
}
|
||||
bcx = take_ty(bcx, val, e_ty);
|
||||
val = load_if_immediate(bcx, val, e_ty);
|
||||
add_clean_temp(bcx, val, e_ty);
|
||||
}
|
||||
} else if type_is_immediate(ccx, e_ty) && !lv.is_mem {
|
||||
@ -4185,7 +4190,7 @@ fn with_out_method(work: fn(&out_method) -> result, cx: @block_ctxt,
|
||||
// immediate-ness of the type.
|
||||
fn type_is_immediate(ccx: &@crate_ctxt, t: ty::t) -> bool {
|
||||
ret ty::type_is_scalar(ccx.tcx, t) || ty::type_is_boxed(ccx.tcx, t) ||
|
||||
ty::type_is_native(ccx.tcx, t) || ty::type_is_vec(ccx.tcx, t);
|
||||
ty::type_is_native(ccx.tcx, t);
|
||||
}
|
||||
|
||||
fn do_spill(cx: &@block_ctxt, v: ValueRef, t: ty::t) -> result {
|
||||
@ -5305,9 +5310,12 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
|
||||
let arg_ty = arg_tys[i].ty;
|
||||
let llargval;
|
||||
if ty::type_is_structural(cx.ccx.tcx, arg_ty) ||
|
||||
ty::type_has_dynamic_size(cx.ccx.tcx, arg_ty) {
|
||||
ty::type_has_dynamic_size(cx.ccx.tcx, arg_ty) ||
|
||||
ty::type_is_unique(cx.ccx.tcx, arg_ty) {
|
||||
llargval = llargptr;
|
||||
} else { llargval = Load(bcx, llargptr); }
|
||||
} else {
|
||||
llargval = Load(bcx, llargptr);
|
||||
}
|
||||
bcx = copy_val(bcx, INIT, lldestptr, llargval, arg_ty);
|
||||
i += 1u;
|
||||
}
|
||||
|
@ -407,8 +407,10 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
||||
}
|
||||
}
|
||||
lit(l) {
|
||||
test_val = Load(bcx, val);
|
||||
kind = alt l.node { ast::lit_str(_) { compare } _ { switch } };
|
||||
kind = alt l.node {
|
||||
ast::lit_str(_) { compare }
|
||||
_ { test_val = Load(bcx, val); switch }
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,19 +7,20 @@ import trans::{call_memmove, trans_shared_malloc, llsize_of, type_of_or_i8,
|
||||
incr_ptr, INIT, copy_val, load_if_immediate, alloca, size_of,
|
||||
llderivedtydescs_block_ctxt, lazily_emit_tydesc_glue,
|
||||
get_tydesc, load_inbounds, move_val_if_temp, trans_lval,
|
||||
node_id_type, new_sub_block_ctxt, tps_normal, do_spill_noroot};
|
||||
node_id_type, new_sub_block_ctxt, tps_normal, do_spill_noroot,
|
||||
GEPi, alloc_ty};
|
||||
import trans_build::*;
|
||||
import trans_common::*;
|
||||
|
||||
fn get_fill(bcx: &@block_ctxt, vptr: ValueRef) -> ValueRef {
|
||||
Load(bcx, InBoundsGEP(bcx, vptr, [C_int(0), C_uint(abi::vec_elt_fill)]))
|
||||
fn get_fill(bcx: &@block_ctxt, vptrptr: ValueRef) -> ValueRef {
|
||||
Load(bcx, GEPi(bcx, Load(bcx, vptrptr), [0, abi::vec_elt_fill as int]))
|
||||
}
|
||||
fn get_alloc(bcx: &@block_ctxt, vptr: ValueRef) -> ValueRef {
|
||||
Load(bcx, InBoundsGEP(bcx, vptr, [C_int(0), C_uint(abi::vec_elt_alloc)]))
|
||||
fn get_alloc(bcx: &@block_ctxt, vptrptr: ValueRef) -> ValueRef {
|
||||
Load(bcx, GEPi(bcx, Load(bcx, vptrptr), [0, abi::vec_elt_alloc as int]))
|
||||
}
|
||||
fn get_dataptr(bcx: &@block_ctxt, vpt: ValueRef, unit_ty: TypeRef) ->
|
||||
fn get_dataptr(bcx: &@block_ctxt, vptrptr: ValueRef, unit_ty: TypeRef) ->
|
||||
ValueRef {
|
||||
let ptr = InBoundsGEP(bcx, vpt, [C_int(0), C_uint(abi::vec_elt_elems)]);
|
||||
let ptr = GEPi(bcx, Load(bcx, vptrptr), [0, abi::vec_elt_elems as int]);
|
||||
PointerCast(bcx, ptr, T_ptr(unit_ty))
|
||||
}
|
||||
|
||||
@ -59,17 +60,22 @@ fn alloc(bcx: &@block_ctxt, vec_ty: &ty::t, elts: uint) -> alloc_result {
|
||||
let alloc = if elts < 4u { Mul(bcx, C_int(4), unit_sz) } else { fill };
|
||||
let {bcx: bcx, val: vptr} = alloc_raw(bcx, fill, alloc);
|
||||
let vptr = PointerCast(bcx, vptr, T_ptr(llvecty));
|
||||
add_clean_temp(bcx, vptr, vec_ty);
|
||||
|
||||
let r = alloc_ty(bcx, vec_ty);
|
||||
let vptrptr = r.val; bcx = r.bcx;
|
||||
|
||||
Store(bcx, vptr, vptrptr);
|
||||
add_clean_temp(bcx, vptrptr, vec_ty);
|
||||
ret {bcx: bcx,
|
||||
val: vptr,
|
||||
val: vptrptr,
|
||||
unit_ty: unit_ty,
|
||||
llunitsz: unit_sz,
|
||||
llunitty: llunitty};
|
||||
}
|
||||
|
||||
fn duplicate(bcx: &@block_ctxt, vptrptr: ValueRef) -> @block_ctxt {
|
||||
let fill = get_fill(bcx, vptrptr);
|
||||
let vptr = Load(bcx, vptrptr);
|
||||
let fill = get_fill(bcx, vptr);
|
||||
let size = Add(bcx, fill, llsize_of(T_opaque_vec()));
|
||||
let {bcx: bcx, val: newptr} =
|
||||
trans_shared_malloc(bcx, val_ty(vptr), size);
|
||||
@ -135,13 +141,13 @@ fn trans_str(bcx: &@block_ctxt, s: str) -> result {
|
||||
}
|
||||
|
||||
fn trans_append(cx: &@block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
|
||||
rhs: ValueRef) -> result {
|
||||
rhsptr: ValueRef) -> result {
|
||||
// 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);
|
||||
if dynamic {
|
||||
lhsptr = PointerCast(cx, lhsptr, T_ptr(T_ptr(T_opaque_vec())));
|
||||
rhs = PointerCast(cx, rhs, T_ptr(T_opaque_vec()));
|
||||
rhsptr = PointerCast(cx, rhsptr, T_ptr(T_ptr(T_opaque_vec())));
|
||||
}
|
||||
let strings =
|
||||
alt ty::struct(bcx_tcx(cx), vec_ty) {
|
||||
@ -152,26 +158,26 @@ fn trans_append(cx: &@block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
|
||||
let {bcx: bcx, val: unit_sz} = size_of(cx, unit_ty);
|
||||
let llunitty = type_of_or_i8(cx, unit_ty);
|
||||
|
||||
let rhs = Load(bcx, rhsptr);
|
||||
let lhs = Load(bcx, lhsptr);
|
||||
let self_append = ICmp(bcx, lib::llvm::LLVMIntEQ, lhs, rhs);
|
||||
let lfill = get_fill(bcx, lhs);
|
||||
let rfill = get_fill(bcx, rhs);
|
||||
let lfill = get_fill(bcx, lhsptr);
|
||||
let rfill = get_fill(bcx, rhsptr);
|
||||
let new_fill = Add(bcx, lfill, rfill);
|
||||
if strings { new_fill = Sub(bcx, new_fill, C_int(1)); }
|
||||
let opaque_lhs = PointerCast(bcx, lhsptr, T_ptr(T_ptr(T_opaque_vec())));
|
||||
Call(bcx, bcx_ccx(cx).upcalls.vec_grow,
|
||||
[cx.fcx.lltaskptr, opaque_lhs, new_fill]);
|
||||
// Was overwritten if we resized
|
||||
let lhs = Load(bcx, lhsptr);
|
||||
let rhs = Select(bcx, self_append, lhs, rhs);
|
||||
rhsptr = Select(bcx, self_append, lhsptr, rhsptr);
|
||||
|
||||
let lhs_data = get_dataptr(bcx, lhs, llunitty);
|
||||
let lhs_data = get_dataptr(bcx, lhsptr, llunitty);
|
||||
let lhs_off = lfill;
|
||||
if strings { lhs_off = Sub(bcx, lhs_off, C_int(1)); }
|
||||
let write_ptr = pointer_add(bcx, lhs_data, lhs_off);
|
||||
let write_ptr_ptr = do_spill_noroot(bcx, write_ptr);
|
||||
let bcx =
|
||||
iter_vec_raw(bcx, rhs, vec_ty, rfill,
|
||||
iter_vec_raw(bcx, rhsptr, vec_ty, rfill,
|
||||
// We have to increment by the dynamically-computed size.
|
||||
{|&bcx, addr, _ty|
|
||||
let write_ptr = Load(bcx, write_ptr_ptr);
|
||||
@ -211,7 +217,8 @@ fn trans_append_literal(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
|
||||
ret bcx;
|
||||
}
|
||||
|
||||
fn trans_add(bcx: &@block_ctxt, vec_ty: ty::t, lhs: ValueRef, rhs: ValueRef)
|
||||
fn trans_add(bcx: &@block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
|
||||
rhsptr: ValueRef)
|
||||
-> result {
|
||||
let strings =
|
||||
alt ty::struct(bcx_tcx(bcx), vec_ty) {
|
||||
@ -222,16 +229,18 @@ fn trans_add(bcx: &@block_ctxt, vec_ty: ty::t, lhs: ValueRef, rhs: ValueRef)
|
||||
let llunitty = type_of_or_i8(bcx, unit_ty);
|
||||
let {bcx: bcx, val: llunitsz} = size_of(bcx, unit_ty);
|
||||
|
||||
let lhs_fill = get_fill(bcx, lhs);
|
||||
let lhs_fill = get_fill(bcx, lhsptr);
|
||||
if strings { lhs_fill = Sub(bcx, lhs_fill, C_int(1)); }
|
||||
let rhs_fill = get_fill(bcx, rhs);
|
||||
let rhs_fill = get_fill(bcx, rhsptr);
|
||||
let new_fill = Add(bcx, lhs_fill, rhs_fill);
|
||||
let {bcx: bcx, val: new_vec} = alloc_raw(bcx, new_fill, new_fill);
|
||||
let new_vec = PointerCast(bcx, new_vec, T_ptr(T_vec(llunitty)));
|
||||
add_clean_temp(bcx, new_vec, vec_ty);
|
||||
let {bcx: bcx, val: new_vec_ptr} = alloc_raw(bcx, new_fill, new_fill);
|
||||
new_vec_ptr = PointerCast(bcx, new_vec_ptr, T_ptr(T_vec(llunitty)));
|
||||
let {bcx: bcx, val: new_vec_ptr_ptr} = alloc_ty(bcx, vec_ty);
|
||||
Store(bcx, new_vec_ptr, new_vec_ptr_ptr);
|
||||
add_clean_temp(bcx, new_vec_ptr_ptr, vec_ty);
|
||||
|
||||
let write_ptr_ptr =
|
||||
do_spill_noroot(bcx, get_dataptr(bcx, new_vec, llunitty));
|
||||
do_spill_noroot(bcx, get_dataptr(bcx, new_vec_ptr_ptr, llunitty));
|
||||
let copy_fn =
|
||||
bind fn (bcx: &@block_ctxt, addr: ValueRef, _ty: ty::t,
|
||||
write_ptr_ptr: ValueRef, unit_ty: ty::t, llunitsz: ValueRef)
|
||||
@ -247,22 +256,22 @@ fn trans_add(bcx: &@block_ctxt, vec_ty: ty::t, lhs: ValueRef, rhs: ValueRef)
|
||||
ret bcx;
|
||||
}(_, _, _, write_ptr_ptr, unit_ty, llunitsz);
|
||||
|
||||
let bcx = iter_vec_raw(bcx, lhs, vec_ty, lhs_fill, copy_fn);
|
||||
let bcx = iter_vec_raw(bcx, rhs, vec_ty, rhs_fill, copy_fn);
|
||||
ret rslt(bcx, new_vec);
|
||||
let bcx = iter_vec_raw(bcx, lhsptr, vec_ty, lhs_fill, copy_fn);
|
||||
let bcx = iter_vec_raw(bcx, rhsptr, vec_ty, rhs_fill, copy_fn);
|
||||
ret rslt(bcx, new_vec_ptr_ptr);
|
||||
}
|
||||
|
||||
type val_and_ty_fn = fn(&@block_ctxt, ValueRef, ty::t) -> result;
|
||||
|
||||
type iter_vec_block = block(&@block_ctxt, ValueRef, ty::t) -> @block_ctxt;
|
||||
|
||||
fn iter_vec_raw(bcx: &@block_ctxt, vptr: ValueRef, vec_ty: ty::t,
|
||||
fn iter_vec_raw(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
|
||||
fill: ValueRef, f: &iter_vec_block) -> @block_ctxt {
|
||||
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
||||
let llunitty = type_of_or_i8(bcx, unit_ty);
|
||||
let {bcx: bcx, val: unit_sz} = size_of(bcx, unit_ty);
|
||||
let vptr = PointerCast(bcx, vptr, T_ptr(T_vec(llunitty)));
|
||||
let data_ptr = get_dataptr(bcx, vptr, llunitty);
|
||||
vptrptr = PointerCast(bcx, vptrptr, T_ptr(T_ptr(T_vec(llunitty))));
|
||||
let data_ptr = get_dataptr(bcx, vptrptr, llunitty);
|
||||
|
||||
// Calculate the last pointer address we want to handle.
|
||||
// TODO: Optimize this when the size of the unit type is statically
|
||||
@ -292,9 +301,8 @@ fn iter_vec_raw(bcx: &@block_ctxt, vptr: ValueRef, vec_ty: ty::t,
|
||||
|
||||
fn iter_vec(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
|
||||
f: &iter_vec_block) -> @block_ctxt {
|
||||
let vptr =
|
||||
Load(bcx, PointerCast(bcx, vptrptr, T_ptr(T_ptr(T_opaque_vec()))));
|
||||
ret iter_vec_raw(bcx, vptr, vec_ty, get_fill(bcx, vptr), f);
|
||||
vptrptr = PointerCast(bcx, vptrptr, T_ptr(T_ptr(T_opaque_vec())));
|
||||
ret iter_vec_raw(bcx, vptrptr, vec_ty, get_fill(bcx, vptrptr), f);
|
||||
}
|
||||
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user