Separate lifetime starts from alloca()
Combining them seemed like a good idea at the time, but turns out that handling lifetimes separately makes it somewhat easier to handle cases where we don't want the intrinsics, and let's you see more easily where the start/end pairs are.
This commit is contained in:
parent
f3bd14ab11
commit
6c512dc52b
10 changed files with 28 additions and 24 deletions
|
@ -1197,7 +1197,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||
monomorphize::field_ty(bcx.tcx(), substs, field)
|
||||
}).unwrap();
|
||||
let llty = type_of::type_of(bcx.ccx(), unsized_ty);
|
||||
let scratch = alloca_no_lifetime(bcx, llty, "__struct_field_fat_ptr");
|
||||
let scratch = alloca(bcx, llty, "__struct_field_fat_ptr");
|
||||
let data = adt::trans_field_ptr(bcx, &*repr, struct_val, 0, arg_count);
|
||||
let len = Load(bcx, expr::get_meta(bcx, val.val));
|
||||
Store(bcx, data, expr::get_dataptr(bcx, scratch));
|
||||
|
@ -1524,12 +1524,8 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
|
|||
match bm {
|
||||
ast::BindByValue(_) if !moves_by_default || reassigned =>
|
||||
{
|
||||
llmatch = alloca_no_lifetime(bcx,
|
||||
llvariable_ty.ptr_to(),
|
||||
"__llmatch");
|
||||
let llcopy = alloca_no_lifetime(bcx,
|
||||
llvariable_ty,
|
||||
&bcx.name(name));
|
||||
llmatch = alloca(bcx, llvariable_ty.ptr_to(), "__llmatch");
|
||||
let llcopy = alloca(bcx, llvariable_ty, &bcx.name(name));
|
||||
trmode = if moves_by_default {
|
||||
TrByMoveIntoCopy(llcopy)
|
||||
} else {
|
||||
|
@ -1540,15 +1536,11 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
|
|||
// in this case, the final type of the variable will be T,
|
||||
// but during matching we need to store a *T as explained
|
||||
// above
|
||||
llmatch = alloca_no_lifetime(bcx,
|
||||
llvariable_ty.ptr_to(),
|
||||
&bcx.name(name));
|
||||
llmatch = alloca(bcx, llvariable_ty.ptr_to(), &bcx.name(name));
|
||||
trmode = TrByMoveRef;
|
||||
}
|
||||
ast::BindByRef(_) => {
|
||||
llmatch = alloca_no_lifetime(bcx,
|
||||
llvariable_ty,
|
||||
&bcx.name(name));
|
||||
llmatch = alloca(bcx, llvariable_ty, &bcx.name(name));
|
||||
trmode = TrByRef;
|
||||
}
|
||||
};
|
||||
|
@ -1749,6 +1741,7 @@ fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
|
|||
|
||||
// Subtle: be sure that we *populate* the memory *before*
|
||||
// we schedule the cleanup.
|
||||
call_lifetime_start(bcx, llval);
|
||||
let bcx = populate(arg, bcx, datum);
|
||||
bcx.fcx.schedule_lifetime_end(cleanup_scope, llval);
|
||||
bcx.fcx.schedule_drop_mem(cleanup_scope, llval, var_ty, lvalue.dropflag_hint(bcx));
|
||||
|
|
|
@ -1025,12 +1025,6 @@ pub fn alloc_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, name: &str) ->
|
|||
}
|
||||
|
||||
pub fn alloca(cx: Block, ty: Type, name: &str) -> ValueRef {
|
||||
let p = alloca_no_lifetime(cx, ty, name);
|
||||
call_lifetime_start(cx, p);
|
||||
p
|
||||
}
|
||||
|
||||
pub fn alloca_no_lifetime(cx: Block, ty: Type, name: &str) -> ValueRef {
|
||||
let _icx = push_ctxt("alloca");
|
||||
if cx.unreachable.get() {
|
||||
unsafe {
|
||||
|
@ -1742,7 +1736,9 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||
expr::SaveIn(d) => d,
|
||||
expr::Ignore => {
|
||||
if !type_is_zero_size(ccx, result_ty) {
|
||||
alloc_ty(bcx, result_ty, "constructor_result")
|
||||
let llresult = alloc_ty(bcx, result_ty, "constructor_result");
|
||||
call_lifetime_start(bcx, llresult);
|
||||
llresult
|
||||
} else {
|
||||
C_undef(type_of::type_of(ccx, result_ty).ptr_to())
|
||||
}
|
||||
|
|
|
@ -725,7 +725,9 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
|||
let llty = type_of::type_of(ccx, ret_ty);
|
||||
Some(common::C_undef(llty.ptr_to()))
|
||||
} else {
|
||||
Some(alloc_ty(bcx, ret_ty, "__llret"))
|
||||
let llresult = alloc_ty(bcx, ret_ty, "__llret");
|
||||
call_lifetime_start(bcx, llresult);
|
||||
Some(llresult)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -883,6 +883,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
|
|||
}
|
||||
None => {
|
||||
let addr = base::alloca(pad_bcx, common::val_ty(llretval), "");
|
||||
base::call_lifetime_start(pad_bcx, addr);
|
||||
self.personality.set(Some(addr));
|
||||
build::Store(pad_bcx, llretval, addr);
|
||||
}
|
||||
|
|
|
@ -504,7 +504,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
|||
output: ty::FnOutput<'tcx>,
|
||||
name: &str) -> ValueRef {
|
||||
if self.needs_ret_allocas {
|
||||
base::alloca_no_lifetime(bcx, match output {
|
||||
base::alloca(bcx, match output {
|
||||
ty::FnConverging(output_type) => type_of::type_of(bcx.ccx(), output_type),
|
||||
ty::FnDiverging => Type::void(bcx.ccx())
|
||||
}, name)
|
||||
|
|
|
@ -306,6 +306,7 @@ pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
|
|||
let scratch = alloca(bcx, llty, name);
|
||||
|
||||
// Subtle. Populate the scratch memory *before* scheduling cleanup.
|
||||
call_lifetime_start(bcx, scratch);
|
||||
let bcx = populate(arg, bcx, scratch);
|
||||
bcx.fcx.schedule_lifetime_end(scope, scratch);
|
||||
bcx.fcx.schedule_drop_mem(scope, scratch, ty, None);
|
||||
|
@ -324,6 +325,7 @@ pub fn rvalue_scratch_datum<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
-> Datum<'tcx, Rvalue> {
|
||||
let llty = type_of::type_of(bcx.ccx(), ty);
|
||||
let scratch = alloca(bcx, llty, name);
|
||||
call_lifetime_start(bcx, scratch);
|
||||
Datum::new(scratch, ty, Rvalue::new(ByRef))
|
||||
}
|
||||
|
||||
|
|
|
@ -248,6 +248,7 @@ pub fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
} else {
|
||||
let llty = type_of::type_of(bcx.ccx(), const_ty);
|
||||
let scratch = alloca(bcx, llty, "const");
|
||||
call_lifetime_start(bcx, scratch);
|
||||
let lldest = if !const_ty.is_structural() {
|
||||
// Cast pointer to slot, because constants have different types.
|
||||
PointerCast(bcx, scratch, val_ty(global))
|
||||
|
@ -412,6 +413,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
let llty = type_of::type_of(bcx.ccx(), target);
|
||||
|
||||
let scratch = alloca(bcx, llty, "__coerce_target");
|
||||
call_lifetime_start(bcx, scratch);
|
||||
let target_datum = Datum::new(scratch, target,
|
||||
Rvalue::new(ByRef));
|
||||
bcx = coerce_unsized(bcx, expr.span, source_datum, target_datum);
|
||||
|
@ -1445,7 +1447,11 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||
// temporary stack slot
|
||||
let addr = match dest {
|
||||
SaveIn(pos) => pos,
|
||||
Ignore => alloc_ty(bcx, ty, "temp"),
|
||||
Ignore => {
|
||||
let llresult = alloc_ty(bcx, ty, "temp");
|
||||
call_lifetime_start(bcx, llresult);
|
||||
llresult
|
||||
}
|
||||
};
|
||||
|
||||
// This scope holds intermediates that must be cleaned should
|
||||
|
|
|
@ -188,6 +188,7 @@ pub fn drop_ty_immediate<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("drop_ty_immediate");
|
||||
let vp = alloca(bcx, type_of(bcx.ccx(), t), "");
|
||||
call_lifetime_start(bcx, vp);
|
||||
store_ty(bcx, v, vp, t);
|
||||
drop_ty_core(bcx, vp, t, debug_loc, skip_dtor, None)
|
||||
}
|
||||
|
|
|
@ -393,7 +393,9 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||
expr::SaveIn(d) => d,
|
||||
expr::Ignore => {
|
||||
if !type_is_zero_size(ccx, ret_ty) {
|
||||
alloc_ty(bcx, ret_ty, "intrinsic_result")
|
||||
let llresult = alloc_ty(bcx, ret_ty, "intrinsic_result");
|
||||
call_lifetime_start(bcx, llresult);
|
||||
llresult
|
||||
} else {
|
||||
C_undef(llret_ty.ptr_to())
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@ pub fn trans_slice_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
// Always create an alloca even if zero-sized, to preserve
|
||||
// the non-null invariant of the inner slice ptr
|
||||
let llfixed = base::alloca(bcx, llfixed_ty, "");
|
||||
call_lifetime_start(bcx, llfixed);
|
||||
|
||||
if count > 0 {
|
||||
// Arrange for the backing array to be cleaned up.
|
||||
|
|
Loading…
Reference in a new issue