diff options
| author | bors <bors@rust-lang.org> | 2015-08-27 20:09:15 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-08-27 20:09:15 +0000 |
| commit | abfa081c10c9401c8a2f858497fbac583bae234d (patch) | |
| tree | e637758d15335649838da2dd4dd5ff7f8e34ae87 | |
| parent | 17b6fcd4589f678700c71bc88daabb5ba2d80bf0 (diff) | |
| parent | 9a15d664a67137028bb0d32eab56698b18356e6d (diff) | |
| download | rust-abfa081c10c9401c8a2f858497fbac583bae234d.tar.gz rust-abfa081c10c9401c8a2f858497fbac583bae234d.zip | |
Auto merge of #27999 - dotdash:lt, r=eddyb
The major change here is in the tiny commit at the end and makes it so that we no longer emit lifetime intrinsics for allocas for function arguments. They are live for the whole function anyway, so the intrinsics add no value. This makes the resulting IR more clear, and reduces the peak memory usage and LLVM times by about 1-4%, depending on the crate. The remaining changes are just preparatory cleanups and fixes for missing lifetime intrinsics.
| -rw-r--r-- | src/librustc_trans/trans/_match.rs | 60 | ||||
| -rw-r--r-- | src/librustc_trans/trans/base.rs | 13 | ||||
| -rw-r--r-- | src/librustc_trans/trans/callee.rs | 4 | ||||
| -rw-r--r-- | src/librustc_trans/trans/cleanup.rs | 6 | ||||
| -rw-r--r-- | src/librustc_trans/trans/common.rs | 2 | ||||
| -rw-r--r-- | src/librustc_trans/trans/datum.rs | 16 | ||||
| -rw-r--r-- | src/librustc_trans/trans/expr.rs | 16 | ||||
| -rw-r--r-- | src/librustc_trans/trans/foreign.rs | 7 | ||||
| -rw-r--r-- | src/librustc_trans/trans/glue.rs | 7 | ||||
| -rw-r--r-- | src/librustc_trans/trans/intrinsic.rs | 5 | ||||
| -rw-r--r-- | src/librustc_trans/trans/tvec.rs | 4 |
11 files changed, 72 insertions, 68 deletions
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index def9fdbb521..e964afc7b69 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"), }, @@ -1192,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_no_lifetime(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)); @@ -1520,12 +1523,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 { @@ -1536,15 +1535,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; } }; @@ -1745,6 +1740,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..28047ee5812 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -1020,17 +1020,10 @@ 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 { - 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 +1735,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..d226bc3f155 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; } @@ -883,6 +884,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..a57b5d1bbde 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,12 +301,10 @@ 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. 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"))) @@ -322,8 +319,8 @@ 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)) } @@ -500,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 + }) } } } diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 0bec181b9b2..20d189a5cd7 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -246,9 +246,8 @@ 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); - // HACK(eddyb) get around issues with lifetime intrinsics. - let scratch = alloca_no_lifetime(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. PointerCast(bcx, scratch, val_ty(global)) @@ -403,10 +402,9 @@ 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); - // HACK(eddyb) get around issues with lifetime intrinsics. - let scratch = alloca_no_lifetime(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)); bcx = coerce_unsized(bcx, expr.span, source_datum, target_datum); @@ -1440,7 +1438,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/foreign.rs b/src/librustc_trans/trans/foreign.rs index b1c85ce54b7..4949539c136 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)); @@ -432,6 +429,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 +440,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 b72f6bbb451..40a290a2715 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -184,9 +184,12 @@ 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); - 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 8b4b810214d..aab22290efe 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()) } @@ -964,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(_) => {} } diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index f3a3268bebb..019c38869b2 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -106,11 +106,11 @@ 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 { // Arrange for the backing array to be cleaned up. |
