From 6e60fdba1794893dbd1855f01fb0f6b32b70137a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 25 Aug 2015 13:49:02 +0200 Subject: [PATCH 1/6] Remove unnecessary temporaries from compare_values() --- src/librustc_trans/trans/_match.rs | 40 ++++++++++++++++-------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index def9fdbb5219a..8f2efa013b25e 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -875,8 +875,10 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>, debug_loc: DebugLoc) -> Result<'blk, 'tcx> { fn compare_str<'blk, 'tcx>(cx: Block<'blk, 'tcx>, - lhs: ValueRef, - rhs: ValueRef, + lhs_data: ValueRef, + lhs_len: ValueRef, + rhs_data: ValueRef, + rhs_len: ValueRef, rhs_t: Ty<'tcx>, debug_loc: DebugLoc) -> Result<'blk, 'tcx> { @@ -884,10 +886,6 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>, None, &format!("comparison of `{}`", rhs_t), StrEqFnLangItem); - let lhs_data = Load(cx, expr::get_dataptr(cx, lhs)); - let lhs_len = Load(cx, expr::get_meta(cx, lhs)); - let rhs_data = Load(cx, expr::get_dataptr(cx, rhs)); - let rhs_len = Load(cx, expr::get_meta(cx, rhs)); callee::trans_lang_call(cx, did, &[lhs_data, lhs_len, rhs_data, rhs_len], None, debug_loc) } @@ -899,7 +897,13 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>, match rhs_t.sty { ty::TyRef(_, mt) => match mt.ty.sty { - ty::TyStr => compare_str(cx, lhs, rhs, rhs_t, debug_loc), + ty::TyStr => { + let lhs_data = Load(cx, expr::get_dataptr(cx, lhs)); + let lhs_len = Load(cx, expr::get_meta(cx, lhs)); + let rhs_data = Load(cx, expr::get_dataptr(cx, rhs)); + let rhs_len = Load(cx, expr::get_meta(cx, rhs)); + compare_str(cx, lhs_data, lhs_len, rhs_data, rhs_len, rhs_t, debug_loc) + } ty::TyArray(ty, _) | ty::TySlice(ty) => match ty.sty { ty::TyUint(ast::TyU8) => { // NOTE: cast &[u8] and &[u8; N] to &str and abuse the str_eq lang item, @@ -907,24 +911,24 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>, let pat_len = val_ty(rhs).element_type().array_length(); let ty_str_slice = cx.tcx().mk_static_str(); - let rhs_str = alloc_ty(cx, ty_str_slice, "rhs_str"); - Store(cx, expr::get_dataptr(cx, rhs), expr::get_dataptr(cx, rhs_str)); - Store(cx, C_uint(cx.ccx(), pat_len), expr::get_meta(cx, rhs_str)); + let rhs_data = GEPi(cx, rhs, &[0, 0]); + let rhs_len = C_uint(cx.ccx(), pat_len); - let lhs_str; + let lhs_data; + let lhs_len; if val_ty(lhs) == val_ty(rhs) { // Both the discriminant and the pattern are thin pointers - lhs_str = alloc_ty(cx, ty_str_slice, "lhs_str"); - Store(cx, expr::get_dataptr(cx, lhs), expr::get_dataptr(cx, lhs_str)); - Store(cx, C_uint(cx.ccx(), pat_len), expr::get_meta(cx, lhs_str)); - } - else { + lhs_data = GEPi(cx, lhs, &[0, 0]); + lhs_len = C_uint(cx.ccx(), pat_len); + } else { // The discriminant is a fat pointer let llty_str_slice = type_of::type_of(cx.ccx(), ty_str_slice).ptr_to(); - lhs_str = PointerCast(cx, lhs, llty_str_slice); + let lhs_str = PointerCast(cx, lhs, llty_str_slice); + lhs_data = Load(cx, expr::get_dataptr(cx, lhs_str)); + lhs_len = Load(cx, expr::get_meta(cx, lhs_str)); } - compare_str(cx, lhs_str, rhs_str, rhs_t, debug_loc) + compare_str(cx, lhs_data, lhs_len, rhs_data, rhs_len, rhs_t, debug_loc) }, _ => cx.sess().bug("only byte strings supported in compare_values"), }, From f3bd14ab112ff77565dbb57a69540bbae2607ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 25 Aug 2015 18:11:15 +0200 Subject: [PATCH 2/6] Turn some alloca_no_lifetime() calls into plain alloca() calls The issues that the comments referred to were fixed before the PR even landed but we never got around to remove the hack of skipping the lifetime start. --- src/librustc_trans/trans/expr.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index efccba91650ca..8d56f8829eea4 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -247,8 +247,7 @@ pub fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, immediate_rvalue(load_ty(bcx, global, const_ty), const_ty) } else { let llty = type_of::type_of(bcx.ccx(), const_ty); - // HACK(eddyb) get around issues with lifetime intrinsics. - let scratch = alloca_no_lifetime(bcx, llty, "const"); + let scratch = alloca(bcx, llty, "const"); let lldest = if !const_ty.is_structural() { // Cast pointer to slot, because constants have different types. PointerCast(bcx, scratch, val_ty(global)) @@ -412,8 +411,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let target = bcx.monomorphize(&target); let llty = type_of::type_of(bcx.ccx(), target); - // HACK(eddyb) get around issues with lifetime intrinsics. - let scratch = alloca_no_lifetime(bcx, llty, "__coerce_target"); + let scratch = alloca(bcx, llty, "__coerce_target"); let target_datum = Datum::new(scratch, target, Rvalue::new(ByRef)); bcx = coerce_unsized(bcx, expr.span, source_datum, target_datum); 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 3/6] 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 8f2efa013b25e..57bac4d4f81bb 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 7cbb7862c61a4..09cab294c47d5 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 efbe542a5e531..266038990ff13 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 ecfbaf5790306..b6acbde5a1348 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 0ae518fea2bd3..80e618861073e 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 2c8123412cddc..44bebe71235b6 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 8d56f8829eea4..4736bbad5c264 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 93b637ecb4f65..15ad7a8fdc32d 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 8b4b810214d2f..93f79b98c8540 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 f3a3268bebbd5..41c6f827958ec 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. From 95337a29789ee856367d52266dea876fb45bafcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 25 Aug 2015 18:27:44 +0200 Subject: [PATCH 4/6] Add missing lifetime intrinsics in a few places --- src/librustc_trans/trans/cleanup.rs | 5 +++-- src/librustc_trans/trans/foreign.rs | 2 ++ src/librustc_trans/trans/glue.rs | 4 +++- src/librustc_trans/trans/intrinsic.rs | 1 + 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index b6acbde5a1348..d226bc3f155df 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -730,8 +730,9 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx let prev_bcx = self.new_block(true, "resume", None); let personality = self.personality.get().expect( "create_landing_pad() should have set this"); - build::Resume(prev_bcx, - build::Load(prev_bcx, personality)); + let lp = build::Load(prev_bcx, personality); + base::call_lifetime_end(prev_bcx, personality); + build::Resume(prev_bcx, lp); prev_llbb = prev_bcx.llbb; break; } diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index b1c85ce54b73f..fa4151348fde2 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -432,6 +432,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // - Truncating foreign type to correct integral type and then // bitcasting to the struct type yields invalid cast errors. let llscratch = base::alloca(bcx, llforeign_ret_ty, "__cast"); + base::call_lifetime_start(bcx, llscratch); Store(bcx, llforeign_retval, llscratch); let llscratch_i8 = BitCast(bcx, llscratch, Type::i8(ccx).ptr_to()); let llretptr_i8 = BitCast(bcx, llretptr, Type::i8(ccx).ptr_to()); @@ -442,6 +443,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, debug!("llrust_size={}", llrust_size); base::call_memcpy(bcx, llretptr_i8, llscratch_i8, C_uint(ccx, llrust_size), llalign as u32); + base::call_lifetime_end(bcx, llscratch); } } diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index 15ad7a8fdc32d..63ac662d4e3e3 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -190,7 +190,9 @@ pub fn drop_ty_immediate<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, 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) + let bcx = drop_ty_core(bcx, vp, t, debug_loc, skip_dtor, None); + call_lifetime_end(bcx, vp); + bcx } pub fn get_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> ValueRef { diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 93f79b98c8540..aab22290efed4 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -966,6 +966,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, match dest { expr::Ignore => { bcx = glue::drop_ty(bcx, llresult, ret_ty, call_debug_location); + call_lifetime_end(bcx, llresult); } expr::SaveIn(_) => {} } From 727a5d543d662231224002c3345f78b0bebf8c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 25 Aug 2015 18:29:24 +0200 Subject: [PATCH 5/6] Prefer alloc_ty() instead of alloca() where possible --- src/librustc_trans/trans/_match.rs | 3 +-- src/librustc_trans/trans/base.rs | 3 +-- src/librustc_trans/trans/datum.rs | 7 ++----- src/librustc_trans/trans/expr.rs | 6 ++---- src/librustc_trans/trans/foreign.rs | 5 +---- src/librustc_trans/trans/glue.rs | 2 +- src/librustc_trans/trans/tvec.rs | 3 +-- 7 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 57bac4d4f81bb..e964afc7b699e 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -1196,8 +1196,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let unsized_ty = def.struct_variant().fields.last().map(|field| { monomorphize::field_ty(bcx.tcx(), substs, field) }).unwrap(); - let llty = type_of::type_of(bcx.ccx(), unsized_ty); - let scratch = alloca(bcx, llty, "__struct_field_fat_ptr"); + let scratch = alloc_ty(bcx, unsized_ty, "__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)); diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 09cab294c47d5..28047ee5812e7 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -1020,8 +1020,7 @@ pub fn alloc_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, name: &str) -> let ccx = bcx.ccx(); let ty = type_of::type_of(ccx, t); assert!(!t.has_param_types()); - let val = alloca(bcx, ty, name); - return val; + alloca(bcx, ty, name) } pub fn alloca(cx: Block, ty: Type, name: &str) -> ValueRef { diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index 44bebe71235b6..e0a65c93669c4 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -101,7 +101,6 @@ use trans::cleanup; use trans::cleanup::{CleanupMethods, DropHintDatum, DropHintMethods}; use trans::expr; use trans::tvec; -use trans::type_of; use middle::ty::Ty; use std::fmt; @@ -302,8 +301,7 @@ pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>, -> DatumBlock<'blk, 'tcx, Lvalue> where F: FnOnce(A, Block<'blk, 'tcx>, ValueRef) -> Block<'blk, 'tcx>, { - let llty = type_of::type_of(bcx.ccx(), ty); - let scratch = alloca(bcx, llty, name); + let scratch = alloc_ty(bcx, ty, name); // Subtle. Populate the scratch memory *before* scheduling cleanup. call_lifetime_start(bcx, scratch); @@ -323,8 +321,7 @@ pub fn rvalue_scratch_datum<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>, name: &str) -> Datum<'tcx, Rvalue> { - let llty = type_of::type_of(bcx.ccx(), ty); - let scratch = alloca(bcx, llty, name); + let scratch = alloc_ty(bcx, ty, 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 4736bbad5c264..b17b3e1395aac 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -246,8 +246,7 @@ pub fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Maybe just get the value directly, instead of loading it? immediate_rvalue(load_ty(bcx, global, const_ty), const_ty) } else { - let llty = type_of::type_of(bcx.ccx(), const_ty); - let scratch = alloca(bcx, llty, "const"); + let scratch = alloc_ty(bcx, const_ty, "const"); call_lifetime_start(bcx, scratch); let lldest = if !const_ty.is_structural() { // Cast pointer to slot, because constants have different types. @@ -410,9 +409,8 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, datum.to_rvalue_datum(bcx, "__coerce_source")); let target = bcx.monomorphize(&target); - let llty = type_of::type_of(bcx.ccx(), target); - let scratch = alloca(bcx, llty, "__coerce_target"); + let scratch = alloc_ty(bcx, target, "__coerce_target"); call_lifetime_start(bcx, scratch); let target_datum = Datum::new(scratch, target, Rvalue::new(ByRef)); diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index fa4151348fde2..4949539c136d0 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -296,10 +296,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Ensure that we always have the Rust value indirectly, // because it makes bitcasting easier. if !rust_indirect { - let scratch = - base::alloca(bcx, - type_of::type_of(ccx, passed_arg_tys[i]), - "__arg"); + let scratch = base::alloc_ty(bcx, passed_arg_tys[i], "__arg"); if type_is_fat_ptr(ccx.tcx(), passed_arg_tys[i]) { Store(bcx, llargs_rust[i + offset], expr::get_dataptr(bcx, scratch)); Store(bcx, llargs_rust[i + offset + 1], expr::get_meta(bcx, scratch)); diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index 63ac662d4e3e3..7a7e043687153 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -187,7 +187,7 @@ pub fn drop_ty_immediate<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, skip_dtor: bool) -> Block<'blk, 'tcx> { let _icx = push_ctxt("drop_ty_immediate"); - let vp = alloca(bcx, type_of(bcx.ccx(), t), ""); + let vp = alloc_ty(bcx, t, ""); call_lifetime_start(bcx, vp); store_ty(bcx, v, vp, t); let bcx = drop_ty_core(bcx, vp, t, debug_loc, skip_dtor, None); diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index 41c6f827958ec..019c38869b27d 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -106,11 +106,10 @@ pub fn trans_slice_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, debug!(" vt={}, count={}", vt.to_string(ccx), count); let fixed_ty = bcx.tcx().mk_array(vt.unit_ty, count); - let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty); // 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, ""); + let llfixed = base::alloc_ty(bcx, fixed_ty, ""); call_lifetime_start(bcx, llfixed); if count > 0 { From 9a15d664a67137028bb0d32eab56698b18356e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 25 Aug 2015 18:33:55 +0200 Subject: [PATCH 6/6] Omit lifetime intrinsics for function arguments and similar top-level items Function arguments are live for the whole function scope, so adding lifetime intrinsics around them adds no value. The same is true for drop hint allocas and everything else that goes directly through lvalue_scratch_datum. So the easiest fix is to emit lifetime intrinsics only for lvalue datums that are created in to_lvalue_datum_in_scope(). The reduces peak memory usage and LLVM times by about 1-4%, depending on the crate. --- src/librustc_trans/trans/datum.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index e0a65c93669c4..a57b5d1bbde26 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -304,9 +304,7 @@ pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>, let scratch = alloc_ty(bcx, ty, 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); DatumBlock::new(bcx, Datum::new(scratch, ty, Lvalue::new("datum::lvalue_scratch_datum"))) @@ -499,7 +497,12 @@ impl<'tcx> Datum<'tcx, Rvalue> { ByValue => { lvalue_scratch_datum( bcx, self.ty, name, scope, self, - |this, bcx, llval| this.store_to(bcx, llval)) + |this, bcx, llval| { + call_lifetime_start(bcx, llval); + let bcx = this.store_to(bcx, llval); + bcx.fcx.schedule_lifetime_end(scope, llval); + bcx + }) } } }