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:
Björn Steinbrink 2015-08-25 18:24:16 +02:00
parent f3bd14ab11
commit 6c512dc52b
10 changed files with 28 additions and 24 deletions

View file

@ -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));

View file

@ -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())
}

View file

@ -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

View file

@ -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);
}

View file

@ -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)

View file

@ -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))
}

View file

@ -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

View file

@ -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)
}

View file

@ -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())
}

View file

@ -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.