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 def9fdbb5219..8f2efa013b25 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 efccba91650c..8d56f8829eea 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 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. 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 b6acbde5a134..d226bc3f155d 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 b1c85ce54b73..fa4151348fde 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 15ad7a8fdc32..63ac662d4e3e 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 93f79b98c854..aab22290efed 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 57bac4d4f81b..e964afc7b699 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 09cab294c47d..28047ee5812e 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 44bebe71235b..e0a65c93669c 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 4736bbad5c26..b17b3e1395aa 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 fa4151348fde..4949539c136d 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 63ac662d4e3e..7a7e04368715 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 41c6f827958e..019c38869b27 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 e0a65c93669c..a57b5d1bbde2 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 + }) } } }