Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of lifetime intrinsics once more #27999

Merged
merged 6 commits into from
Aug 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 28 additions & 32 deletions src/librustc_trans/trans/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -875,19 +875,17 @@ 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> {
let did = langcall(cx,
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)
}

Expand All @@ -899,32 +897,38 @@ 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,
// which calls memcmp().
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"),
},
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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 {
Expand All @@ -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;
}
};
Expand Down Expand Up @@ -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));
Expand Down
13 changes: 4 additions & 9 deletions src/librustc_trans/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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())
}
Expand Down
4 changes: 3 additions & 1 deletion src/librustc_trans/trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions src/librustc_trans/trans/cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
16 changes: 9 additions & 7 deletions src/librustc_trans/trans/datum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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")))
Expand All @@ -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))
}

Expand Down Expand Up @@ -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
})
}
}
}
Expand Down
16 changes: 9 additions & 7 deletions src/librustc_trans/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -410,10 +409,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);
Expand Down Expand Up @@ -1447,7 +1445,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
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_trans/trans/foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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());
Expand All @@ -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);
}
}

Expand Down
7 changes: 5 additions & 2 deletions src/librustc_trans/trans/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,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 {
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_trans/trans/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
Expand Down Expand Up @@ -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(_) => {}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/trans/tvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down