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 usage of lifetime intrinsics in match expressions #15921

Merged
merged 1 commit into from
Jul 24, 2014
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
27 changes: 22 additions & 5 deletions src/librustc/middle/trans/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,12 @@ fn insert_lllocals<'a>(mut bcx: &'a Block<'a>, bindings_map: &BindingsMap,
TrByCopy(llbinding) => {
let llval = Load(bcx, binding_info.llmatch);
let datum = Datum::new(llval, binding_info.ty, Lvalue);
call_lifetime_start(bcx, llbinding);
bcx = datum.store_to(bcx, llbinding);
match cs {
Some(cs) => bcx.fcx.schedule_lifetime_end(cs, llbinding),
_ => {}
}

llbinding
},
Expand All @@ -906,7 +911,10 @@ fn insert_lllocals<'a>(mut bcx: &'a Block<'a>, bindings_map: &BindingsMap,

let datum = Datum::new(llval, binding_info.ty, Lvalue);
match cs {
Some(cs) => bcx.fcx.schedule_drop_and_zero_mem(cs, llval, binding_info.ty),
Some(cs) => {
bcx.fcx.schedule_drop_and_zero_mem(cs, llval, binding_info.ty);
bcx.fcx.schedule_lifetime_end(cs, binding_info.llmatch);
}
_ => {}
}

Expand Down Expand Up @@ -945,9 +953,17 @@ fn compile_guard<'a, 'b>(
let val = unpack_datum!(bcx, expr::trans(bcx, guard_expr));
let val = val.to_llbool(bcx);

for (_, &binding_info) in data.bindings_map.iter() {
match binding_info.trmode {
TrByCopy(llbinding) => call_lifetime_end(bcx, llbinding),
_ => {}
}
}

return with_cond(bcx, Not(bcx, val), |bcx| {
// Guard does not match: remove all bindings from the lllocals table
for (_, &binding_info) in data.bindings_map.iter() {
call_lifetime_end(bcx, binding_info.llmatch);
bcx.fcx.lllocals.borrow_mut().remove(&binding_info.id);
}
match chk {
Expand Down Expand Up @@ -988,6 +1004,7 @@ fn compile_submatch<'a, 'b>(
let data = &m[0].data;
for &(ref ident, ref value_ptr) in m[0].bound_ptrs.iter() {
let llmatch = data.bindings_map.get(ident).llmatch;
call_lifetime_start(bcx, llmatch);
Store(bcx, *value_ptr, llmatch);
}
match data.arm.guard {
Expand Down Expand Up @@ -1294,24 +1311,24 @@ fn create_bindings_map(bcx: &Block, pat: Gc<ast::Pat>) -> BindingsMap {
match bm {
ast::BindByValue(_)
if !ty::type_moves_by_default(tcx, variable_ty) => {
llmatch = alloca(bcx,
llmatch = alloca_no_lifetime(bcx,
llvariable_ty.ptr_to(),
"__llmatch");
trmode = TrByCopy(alloca(bcx,
trmode = TrByCopy(alloca_no_lifetime(bcx,
llvariable_ty,
bcx.ident(ident).as_slice()));
}
ast::BindByValue(_) => {
// 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(bcx,
llmatch = alloca_no_lifetime(bcx,
llvariable_ty.ptr_to(),
bcx.ident(ident).as_slice());
trmode = TrByMove;
}
ast::BindByRef(_) => {
llmatch = alloca(bcx,
llmatch = alloca_no_lifetime(bcx,
llvariable_ty,
bcx.ident(ident).as_slice());
trmode = TrByRef;
Expand Down
25 changes: 16 additions & 9 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1169,25 +1169,32 @@ pub fn alloc_ty(bcx: &Block, t: ty::t, name: &str) -> ValueRef {
}

pub fn alloca(cx: &Block, ty: Type, name: &str) -> ValueRef {
alloca_maybe_zeroed(cx, ty, name, false)
let p = alloca_no_lifetime(cx, ty, name);
call_lifetime_start(cx, p);
p
}

pub fn alloca_maybe_zeroed(cx: &Block, ty: Type, name: &str, zero: bool) -> ValueRef {
pub fn alloca_no_lifetime(cx: &Block, ty: Type, name: &str) -> ValueRef {
let _icx = push_ctxt("alloca");
if cx.unreachable.get() {
unsafe {
return llvm::LLVMGetUndef(ty.ptr_to().to_ref());
}
}
debuginfo::clear_source_location(cx.fcx);
let p = Alloca(cx, ty, name);
if zero {
let b = cx.fcx.ccx.builder();
b.position_before(cx.fcx.alloca_insert_pt.get().unwrap());
memzero(&b, p, ty);
} else {
call_lifetime_start(cx, p);
Alloca(cx, ty, name)
}

pub fn alloca_zeroed(cx: &Block, ty: Type, name: &str) -> ValueRef {
if cx.unreachable.get() {
unsafe {
return llvm::LLVMGetUndef(ty.ptr_to().to_ref());
}
}
let p = alloca_no_lifetime(cx, ty, name);
let b = cx.fcx.ccx.builder();
b.position_before(cx.fcx.alloca_insert_pt.get().unwrap());
memzero(&b, p, ty);
p
}

Expand Down
8 changes: 6 additions & 2 deletions src/librustc/middle/trans/datum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,11 @@ pub fn lvalue_scratch_datum<'a, A>(bcx: &'a Block<'a>,
*/

let llty = type_of::type_of(bcx.ccx(), ty);
let scratch = alloca_maybe_zeroed(bcx, llty, name, zero);
let scratch = if zero {
alloca_zeroed(bcx, llty, name)
} else {
alloca(bcx, llty, name)
};

// Subtle. Populate the scratch memory *before* scheduling cleanup.
let bcx = populate(arg, bcx, scratch);
Expand All @@ -145,7 +149,7 @@ pub fn rvalue_scratch_datum(bcx: &Block,
*/

let llty = type_of::type_of(bcx.ccx(), ty);
let scratch = alloca_maybe_zeroed(bcx, llty, name, false);
let scratch = alloca(bcx, llty, name);
Datum::new(scratch, ty, Rvalue::new(ByRef))
}

Expand Down