Factored out private routine for emitting LLVM lifetime intrinsic calls.

(The reason this is not factored as far as possible because a
subsequent commit is going to need to do construction without having
access to a `cx`.)
This commit is contained in:
Felix S. Klock II 2016-01-12 17:17:50 +01:00
parent df1283cd1a
commit 8168765d43

View file

@ -1147,48 +1147,63 @@ pub fn with_cond<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, val: ValueRef, f: F) ->
next_cx
}
pub fn call_lifetime_start(cx: Block, ptr: ValueRef) {
if cx.sess().opts.optimize == config::No {
enum Lifetime { Start, End }
// If LLVM lifetime intrinsic support is enabled (i.e. optimizations
// on), and `ptr` is nonzero-sized, then extracts the size of `ptr`
// and the intrinsic for `lt` and passes them to `emit`, which is in
// charge of generating code to call the passed intrinsic on whatever
// block of generated code is targetted for the intrinsic.
//
// If LLVM lifetime intrinsic support is disabled (i.e. optimizations
// off) or `ptr` is zero-sized, then no-op (does not call `emit`).
fn core_lifetime_emit<'blk, 'tcx, F>(ccx: &'blk CrateContext<'blk, 'tcx>,
ptr: ValueRef,
lt: Lifetime,
emit: F)
where F: FnOnce(&'blk CrateContext<'blk, 'tcx>, machine::llsize, ValueRef)
{
if ccx.sess().opts.optimize == config::No {
return;
}
let _icx = push_ctxt("lifetime_start");
let ccx = cx.ccx();
let _icx = push_ctxt(match lt {
Lifetime::Start => "lifetime_start",
Lifetime::End => "lifetime_end"
});
let size = machine::llsize_of_alloc(ccx, val_ty(ptr).element_type());
if size == 0 {
return;
}
let ptr = PointerCast(cx, ptr, Type::i8p(ccx));
let lifetime_start = ccx.get_intrinsic(&"llvm.lifetime.start");
Call(cx,
lifetime_start,
&[C_u64(ccx, size), ptr],
None,
DebugLoc::None);
let lifetime_intrinsic = ccx.get_intrinsic(match lt {
Lifetime::Start => "llvm.lifetime.start",
Lifetime::End => "llvm.lifetime.end"
});
emit(ccx, size, lifetime_intrinsic)
}
pub fn call_lifetime_start(cx: Block, ptr: ValueRef) {
core_lifetime_emit(cx.ccx(), ptr, Lifetime::Start, |ccx, size, lifetime_start| {
let ptr = PointerCast(cx, ptr, Type::i8p(ccx));
Call(cx,
lifetime_start,
&[C_u64(ccx, size), ptr],
None,
DebugLoc::None);
})
}
pub fn call_lifetime_end(cx: Block, ptr: ValueRef) {
if cx.sess().opts.optimize == config::No {
return;
}
let _icx = push_ctxt("lifetime_end");
let ccx = cx.ccx();
let size = machine::llsize_of_alloc(ccx, val_ty(ptr).element_type());
if size == 0 {
return;
}
let ptr = PointerCast(cx, ptr, Type::i8p(ccx));
let lifetime_end = ccx.get_intrinsic(&"llvm.lifetime.end");
Call(cx,
lifetime_end,
&[C_u64(ccx, size), ptr],
None,
DebugLoc::None);
core_lifetime_emit(cx.ccx(), ptr, Lifetime::End, |ccx, size, lifetime_end| {
let ptr = PointerCast(cx, ptr, Type::i8p(ccx));
Call(cx,
lifetime_end,
&[C_u64(ccx, size), ptr],
None,
DebugLoc::None);
})
}
// Generates code for resumption of unwind at the end of a landing pad.