From 6c512dc52b6ddea8137e3e44effee7f140ed1f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 25 Aug 2015 18:24:16 +0200 Subject: [PATCH] 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. --- src/librustc_trans/trans/_match.rs | 19 ++++++------------- src/librustc_trans/trans/base.rs | 10 +++------- src/librustc_trans/trans/callee.rs | 4 +++- src/librustc_trans/trans/cleanup.rs | 1 + src/librustc_trans/trans/common.rs | 2 +- src/librustc_trans/trans/datum.rs | 2 ++ src/librustc_trans/trans/expr.rs | 8 +++++++- src/librustc_trans/trans/glue.rs | 1 + src/librustc_trans/trans/intrinsic.rs | 4 +++- src/librustc_trans/trans/tvec.rs | 1 + 10 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 8f2efa013b25..57bac4d4f81b 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -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)); diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 7cbb7862c61a..09cab294c47d 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -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()) } diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index efbe542a5e53..266038990ff1 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -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 diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index ecfbaf579030..b6acbde5a134 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -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); } diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 0ae518fea2bd..80e618861073 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -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) diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index 2c8123412cdd..44bebe71235b 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -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)) } diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 8d56f8829eea..4736bbad5c26 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -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 diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index 93b637ecb4f6..15ad7a8fdc32 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -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) } diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 8b4b810214d2..93f79b98c854 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -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()) } diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index f3a3268bebbd..41c6f827958e 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -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.