Skip to content

Commit abfa081

Browse files
committed
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.
2 parents 17b6fcd + 9a15d66 commit abfa081

File tree

11 files changed

+72
-68
lines changed

11 files changed

+72
-68
lines changed

src/librustc_trans/trans/_match.rs

+28-32
Original file line numberDiff line numberDiff line change
@@ -875,19 +875,17 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
875875
debug_loc: DebugLoc)
876876
-> Result<'blk, 'tcx> {
877877
fn compare_str<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
878-
lhs: ValueRef,
879-
rhs: ValueRef,
878+
lhs_data: ValueRef,
879+
lhs_len: ValueRef,
880+
rhs_data: ValueRef,
881+
rhs_len: ValueRef,
880882
rhs_t: Ty<'tcx>,
881883
debug_loc: DebugLoc)
882884
-> Result<'blk, 'tcx> {
883885
let did = langcall(cx,
884886
None,
885887
&format!("comparison of `{}`", rhs_t),
886888
StrEqFnLangItem);
887-
let lhs_data = Load(cx, expr::get_dataptr(cx, lhs));
888-
let lhs_len = Load(cx, expr::get_meta(cx, lhs));
889-
let rhs_data = Load(cx, expr::get_dataptr(cx, rhs));
890-
let rhs_len = Load(cx, expr::get_meta(cx, rhs));
891889
callee::trans_lang_call(cx, did, &[lhs_data, lhs_len, rhs_data, rhs_len], None, debug_loc)
892890
}
893891

@@ -899,32 +897,38 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
899897

900898
match rhs_t.sty {
901899
ty::TyRef(_, mt) => match mt.ty.sty {
902-
ty::TyStr => compare_str(cx, lhs, rhs, rhs_t, debug_loc),
900+
ty::TyStr => {
901+
let lhs_data = Load(cx, expr::get_dataptr(cx, lhs));
902+
let lhs_len = Load(cx, expr::get_meta(cx, lhs));
903+
let rhs_data = Load(cx, expr::get_dataptr(cx, rhs));
904+
let rhs_len = Load(cx, expr::get_meta(cx, rhs));
905+
compare_str(cx, lhs_data, lhs_len, rhs_data, rhs_len, rhs_t, debug_loc)
906+
}
903907
ty::TyArray(ty, _) | ty::TySlice(ty) => match ty.sty {
904908
ty::TyUint(ast::TyU8) => {
905909
// NOTE: cast &[u8] and &[u8; N] to &str and abuse the str_eq lang item,
906910
// which calls memcmp().
907911
let pat_len = val_ty(rhs).element_type().array_length();
908912
let ty_str_slice = cx.tcx().mk_static_str();
909913

910-
let rhs_str = alloc_ty(cx, ty_str_slice, "rhs_str");
911-
Store(cx, expr::get_dataptr(cx, rhs), expr::get_dataptr(cx, rhs_str));
912-
Store(cx, C_uint(cx.ccx(), pat_len), expr::get_meta(cx, rhs_str));
914+
let rhs_data = GEPi(cx, rhs, &[0, 0]);
915+
let rhs_len = C_uint(cx.ccx(), pat_len);
913916

914-
let lhs_str;
917+
let lhs_data;
918+
let lhs_len;
915919
if val_ty(lhs) == val_ty(rhs) {
916920
// Both the discriminant and the pattern are thin pointers
917-
lhs_str = alloc_ty(cx, ty_str_slice, "lhs_str");
918-
Store(cx, expr::get_dataptr(cx, lhs), expr::get_dataptr(cx, lhs_str));
919-
Store(cx, C_uint(cx.ccx(), pat_len), expr::get_meta(cx, lhs_str));
920-
}
921-
else {
921+
lhs_data = GEPi(cx, lhs, &[0, 0]);
922+
lhs_len = C_uint(cx.ccx(), pat_len);
923+
} else {
922924
// The discriminant is a fat pointer
923925
let llty_str_slice = type_of::type_of(cx.ccx(), ty_str_slice).ptr_to();
924-
lhs_str = PointerCast(cx, lhs, llty_str_slice);
926+
let lhs_str = PointerCast(cx, lhs, llty_str_slice);
927+
lhs_data = Load(cx, expr::get_dataptr(cx, lhs_str));
928+
lhs_len = Load(cx, expr::get_meta(cx, lhs_str));
925929
}
926930

927-
compare_str(cx, lhs_str, rhs_str, rhs_t, debug_loc)
931+
compare_str(cx, lhs_data, lhs_len, rhs_data, rhs_len, rhs_t, debug_loc)
928932
},
929933
_ => cx.sess().bug("only byte strings supported in compare_values"),
930934
},
@@ -1192,8 +1196,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
11921196
let unsized_ty = def.struct_variant().fields.last().map(|field| {
11931197
monomorphize::field_ty(bcx.tcx(), substs, field)
11941198
}).unwrap();
1195-
let llty = type_of::type_of(bcx.ccx(), unsized_ty);
1196-
let scratch = alloca_no_lifetime(bcx, llty, "__struct_field_fat_ptr");
1199+
let scratch = alloc_ty(bcx, unsized_ty, "__struct_field_fat_ptr");
11971200
let data = adt::trans_field_ptr(bcx, &*repr, struct_val, 0, arg_count);
11981201
let len = Load(bcx, expr::get_meta(bcx, val.val));
11991202
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,
15201523
match bm {
15211524
ast::BindByValue(_) if !moves_by_default || reassigned =>
15221525
{
1523-
llmatch = alloca_no_lifetime(bcx,
1524-
llvariable_ty.ptr_to(),
1525-
"__llmatch");
1526-
let llcopy = alloca_no_lifetime(bcx,
1527-
llvariable_ty,
1528-
&bcx.name(name));
1526+
llmatch = alloca(bcx, llvariable_ty.ptr_to(), "__llmatch");
1527+
let llcopy = alloca(bcx, llvariable_ty, &bcx.name(name));
15291528
trmode = if moves_by_default {
15301529
TrByMoveIntoCopy(llcopy)
15311530
} else {
@@ -1536,15 +1535,11 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
15361535
// in this case, the final type of the variable will be T,
15371536
// but during matching we need to store a *T as explained
15381537
// above
1539-
llmatch = alloca_no_lifetime(bcx,
1540-
llvariable_ty.ptr_to(),
1541-
&bcx.name(name));
1538+
llmatch = alloca(bcx, llvariable_ty.ptr_to(), &bcx.name(name));
15421539
trmode = TrByMoveRef;
15431540
}
15441541
ast::BindByRef(_) => {
1545-
llmatch = alloca_no_lifetime(bcx,
1546-
llvariable_ty,
1547-
&bcx.name(name));
1542+
llmatch = alloca(bcx, llvariable_ty, &bcx.name(name));
15481543
trmode = TrByRef;
15491544
}
15501545
};
@@ -1745,6 +1740,7 @@ fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
17451740

17461741
// Subtle: be sure that we *populate* the memory *before*
17471742
// we schedule the cleanup.
1743+
call_lifetime_start(bcx, llval);
17481744
let bcx = populate(arg, bcx, datum);
17491745
bcx.fcx.schedule_lifetime_end(cleanup_scope, llval);
17501746
bcx.fcx.schedule_drop_mem(cleanup_scope, llval, var_ty, lvalue.dropflag_hint(bcx));

src/librustc_trans/trans/base.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -1020,17 +1020,10 @@ pub fn alloc_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, name: &str) ->
10201020
let ccx = bcx.ccx();
10211021
let ty = type_of::type_of(ccx, t);
10221022
assert!(!t.has_param_types());
1023-
let val = alloca(bcx, ty, name);
1024-
return val;
1023+
alloca(bcx, ty, name)
10251024
}
10261025

10271026
pub fn alloca(cx: Block, ty: Type, name: &str) -> ValueRef {
1028-
let p = alloca_no_lifetime(cx, ty, name);
1029-
call_lifetime_start(cx, p);
1030-
p
1031-
}
1032-
1033-
pub fn alloca_no_lifetime(cx: Block, ty: Type, name: &str) -> ValueRef {
10341027
let _icx = push_ctxt("alloca");
10351028
if cx.unreachable.get() {
10361029
unsafe {
@@ -1742,7 +1735,9 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
17421735
expr::SaveIn(d) => d,
17431736
expr::Ignore => {
17441737
if !type_is_zero_size(ccx, result_ty) {
1745-
alloc_ty(bcx, result_ty, "constructor_result")
1738+
let llresult = alloc_ty(bcx, result_ty, "constructor_result");
1739+
call_lifetime_start(bcx, llresult);
1740+
llresult
17461741
} else {
17471742
C_undef(type_of::type_of(ccx, result_ty).ptr_to())
17481743
}

src/librustc_trans/trans/callee.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,9 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
725725
let llty = type_of::type_of(ccx, ret_ty);
726726
Some(common::C_undef(llty.ptr_to()))
727727
} else {
728-
Some(alloc_ty(bcx, ret_ty, "__llret"))
728+
let llresult = alloc_ty(bcx, ret_ty, "__llret");
729+
call_lifetime_start(bcx, llresult);
730+
Some(llresult)
729731
}
730732
} else {
731733
None

src/librustc_trans/trans/cleanup.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -730,8 +730,9 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
730730
let prev_bcx = self.new_block(true, "resume", None);
731731
let personality = self.personality.get().expect(
732732
"create_landing_pad() should have set this");
733-
build::Resume(prev_bcx,
734-
build::Load(prev_bcx, personality));
733+
let lp = build::Load(prev_bcx, personality);
734+
base::call_lifetime_end(prev_bcx, personality);
735+
build::Resume(prev_bcx, lp);
735736
prev_llbb = prev_bcx.llbb;
736737
break;
737738
}
@@ -883,6 +884,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
883884
}
884885
None => {
885886
let addr = base::alloca(pad_bcx, common::val_ty(llretval), "");
887+
base::call_lifetime_start(pad_bcx, addr);
886888
self.personality.set(Some(addr));
887889
build::Store(pad_bcx, llretval, addr);
888890
}

src/librustc_trans/trans/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
504504
output: ty::FnOutput<'tcx>,
505505
name: &str) -> ValueRef {
506506
if self.needs_ret_allocas {
507-
base::alloca_no_lifetime(bcx, match output {
507+
base::alloca(bcx, match output {
508508
ty::FnConverging(output_type) => type_of::type_of(bcx.ccx(), output_type),
509509
ty::FnDiverging => Type::void(bcx.ccx())
510510
}, name)

src/librustc_trans/trans/datum.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ use trans::cleanup;
101101
use trans::cleanup::{CleanupMethods, DropHintDatum, DropHintMethods};
102102
use trans::expr;
103103
use trans::tvec;
104-
use trans::type_of;
105104
use middle::ty::Ty;
106105

107106
use std::fmt;
@@ -302,12 +301,10 @@ pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
302301
-> DatumBlock<'blk, 'tcx, Lvalue> where
303302
F: FnOnce(A, Block<'blk, 'tcx>, ValueRef) -> Block<'blk, 'tcx>,
304303
{
305-
let llty = type_of::type_of(bcx.ccx(), ty);
306-
let scratch = alloca(bcx, llty, name);
304+
let scratch = alloc_ty(bcx, ty, name);
307305

308306
// Subtle. Populate the scratch memory *before* scheduling cleanup.
309307
let bcx = populate(arg, bcx, scratch);
310-
bcx.fcx.schedule_lifetime_end(scope, scratch);
311308
bcx.fcx.schedule_drop_mem(scope, scratch, ty, None);
312309

313310
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>,
322319
ty: Ty<'tcx>,
323320
name: &str)
324321
-> Datum<'tcx, Rvalue> {
325-
let llty = type_of::type_of(bcx.ccx(), ty);
326-
let scratch = alloca(bcx, llty, name);
322+
let scratch = alloc_ty(bcx, ty, name);
323+
call_lifetime_start(bcx, scratch);
327324
Datum::new(scratch, ty, Rvalue::new(ByRef))
328325
}
329326

@@ -500,7 +497,12 @@ impl<'tcx> Datum<'tcx, Rvalue> {
500497
ByValue => {
501498
lvalue_scratch_datum(
502499
bcx, self.ty, name, scope, self,
503-
|this, bcx, llval| this.store_to(bcx, llval))
500+
|this, bcx, llval| {
501+
call_lifetime_start(bcx, llval);
502+
let bcx = this.store_to(bcx, llval);
503+
bcx.fcx.schedule_lifetime_end(scope, llval);
504+
bcx
505+
})
504506
}
505507
}
506508
}

src/librustc_trans/trans/expr.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,8 @@ pub fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
246246
// Maybe just get the value directly, instead of loading it?
247247
immediate_rvalue(load_ty(bcx, global, const_ty), const_ty)
248248
} else {
249-
let llty = type_of::type_of(bcx.ccx(), const_ty);
250-
// HACK(eddyb) get around issues with lifetime intrinsics.
251-
let scratch = alloca_no_lifetime(bcx, llty, "const");
249+
let scratch = alloc_ty(bcx, const_ty, "const");
250+
call_lifetime_start(bcx, scratch);
252251
let lldest = if !const_ty.is_structural() {
253252
// Cast pointer to slot, because constants have different types.
254253
PointerCast(bcx, scratch, val_ty(global))
@@ -403,10 +402,9 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
403402
datum.to_rvalue_datum(bcx, "__coerce_source"));
404403

405404
let target = bcx.monomorphize(&target);
406-
let llty = type_of::type_of(bcx.ccx(), target);
407405

408-
// HACK(eddyb) get around issues with lifetime intrinsics.
409-
let scratch = alloca_no_lifetime(bcx, llty, "__coerce_target");
406+
let scratch = alloc_ty(bcx, target, "__coerce_target");
407+
call_lifetime_start(bcx, scratch);
410408
let target_datum = Datum::new(scratch, target,
411409
Rvalue::new(ByRef));
412410
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>,
14401438
// temporary stack slot
14411439
let addr = match dest {
14421440
SaveIn(pos) => pos,
1443-
Ignore => alloc_ty(bcx, ty, "temp"),
1441+
Ignore => {
1442+
let llresult = alloc_ty(bcx, ty, "temp");
1443+
call_lifetime_start(bcx, llresult);
1444+
llresult
1445+
}
14441446
};
14451447

14461448
// This scope holds intermediates that must be cleaned should

src/librustc_trans/trans/foreign.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
296296
// Ensure that we always have the Rust value indirectly,
297297
// because it makes bitcasting easier.
298298
if !rust_indirect {
299-
let scratch =
300-
base::alloca(bcx,
301-
type_of::type_of(ccx, passed_arg_tys[i]),
302-
"__arg");
299+
let scratch = base::alloc_ty(bcx, passed_arg_tys[i], "__arg");
303300
if type_is_fat_ptr(ccx.tcx(), passed_arg_tys[i]) {
304301
Store(bcx, llargs_rust[i + offset], expr::get_dataptr(bcx, scratch));
305302
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>,
432429
// - Truncating foreign type to correct integral type and then
433430
// bitcasting to the struct type yields invalid cast errors.
434431
let llscratch = base::alloca(bcx, llforeign_ret_ty, "__cast");
432+
base::call_lifetime_start(bcx, llscratch);
435433
Store(bcx, llforeign_retval, llscratch);
436434
let llscratch_i8 = BitCast(bcx, llscratch, Type::i8(ccx).ptr_to());
437435
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>,
442440
debug!("llrust_size={}", llrust_size);
443441
base::call_memcpy(bcx, llretptr_i8, llscratch_i8,
444442
C_uint(ccx, llrust_size), llalign as u32);
443+
base::call_lifetime_end(bcx, llscratch);
445444
}
446445
}
447446

src/librustc_trans/trans/glue.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,12 @@ pub fn drop_ty_immediate<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
184184
skip_dtor: bool)
185185
-> Block<'blk, 'tcx> {
186186
let _icx = push_ctxt("drop_ty_immediate");
187-
let vp = alloca(bcx, type_of(bcx.ccx(), t), "");
187+
let vp = alloc_ty(bcx, t, "");
188+
call_lifetime_start(bcx, vp);
188189
store_ty(bcx, v, vp, t);
189-
drop_ty_core(bcx, vp, t, debug_loc, skip_dtor, None)
190+
let bcx = drop_ty_core(bcx, vp, t, debug_loc, skip_dtor, None);
191+
call_lifetime_end(bcx, vp);
192+
bcx
190193
}
191194

192195
pub fn get_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> ValueRef {

src/librustc_trans/trans/intrinsic.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,9 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
393393
expr::SaveIn(d) => d,
394394
expr::Ignore => {
395395
if !type_is_zero_size(ccx, ret_ty) {
396-
alloc_ty(bcx, ret_ty, "intrinsic_result")
396+
let llresult = alloc_ty(bcx, ret_ty, "intrinsic_result");
397+
call_lifetime_start(bcx, llresult);
398+
llresult
397399
} else {
398400
C_undef(llret_ty.ptr_to())
399401
}
@@ -964,6 +966,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
964966
match dest {
965967
expr::Ignore => {
966968
bcx = glue::drop_ty(bcx, llresult, ret_ty, call_debug_location);
969+
call_lifetime_end(bcx, llresult);
967970
}
968971
expr::SaveIn(_) => {}
969972
}

src/librustc_trans/trans/tvec.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,11 @@ pub fn trans_slice_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
106106
debug!(" vt={}, count={}", vt.to_string(ccx), count);
107107

108108
let fixed_ty = bcx.tcx().mk_array(vt.unit_ty, count);
109-
let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty);
110109

111110
// Always create an alloca even if zero-sized, to preserve
112111
// the non-null invariant of the inner slice ptr
113-
let llfixed = base::alloca(bcx, llfixed_ty, "");
112+
let llfixed = base::alloc_ty(bcx, fixed_ty, "");
113+
call_lifetime_start(bcx, llfixed);
114114

115115
if count > 0 {
116116
// Arrange for the backing array to be cleaned up.

0 commit comments

Comments
 (0)