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 8f2efa013b2..57bac4d4f81 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 7cbb7862c61..09cab294c47 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 efbe542a5e5..266038990ff 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 ecfbaf57903..b6acbde5a13 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 0ae518fea2b..80e61886107 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 2c8123412cd..44bebe71235 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 8d56f8829ee..4736bbad5c2 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 93b637ecb4f..15ad7a8fdc3 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 8b4b810214d..93f79b98c85 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 f3a3268bebb..41c6f827958 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.