Fix and optimize init intrinsic

This commit is contained in:
bjorn3 2019-02-24 16:46:11 +01:00
parent 16f4126656
commit 970d164089
3 changed files with 58 additions and 9 deletions

View File

@ -371,6 +371,7 @@ pub mod intrinsics {
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
pub fn transmute<T, U>(e: T) -> U;
pub fn uninit<T>() -> T;
pub fn init<T>() -> T;
pub fn ctlz_nonzero<T>(x: T) -> T;
pub fn needs_drop<T>() -> bool;
pub fn bitreverse<T>(x: T) -> T;

View File

@ -165,6 +165,29 @@ fn main() {
struct MyDst<T: ?Sized>(T);
intrinsics::size_of_val(&MyDst([0u8; 4]) as &MyDst<[u8]>);
struct Foo {
x: u8,
y: !,
}
unsafe fn zeroed<T>() -> T {
intrinsics::init::<T>()
}
unsafe fn uninitialized<T>() -> T {
intrinsics::uninit::<T>()
}
#[allow(unreachable_code)]
{
if false {
zeroed::<!>();
zeroed::<Foo>();
zeroed::<(u8, u8)>();
uninitialized::<Foo>();
}
}
}
let _ = box NoisyDrop {

View File

@ -337,16 +337,36 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
let dst_layout = fx.layout_of(dst_ty);
ret.write_cvalue(fx, CValue::ByRef(addr, dst_layout))
};
init, <T> () {
let layout = fx.layout_of(T);
let inited_place = CPlace::new_stack_slot(fx, T);
let addr = inited_place.to_addr(fx);
let zero_val = fx.bcx.ins().iconst(types::I8, 0);
let len_val = fx.bcx.ins().iconst(pointer_ty(fx.tcx), layout.size.bytes() as i64);
fx.bcx.call_memset(fx.module.target_config(), addr, zero_val, len_val);
init, () {
if ret.layout().abi == Abi::Uninhabited {
crate::trap::trap_panic(&mut fx.bcx);
return;
}
let inited_val = inited_place.to_cvalue(fx);
ret.write_cvalue(fx, inited_val);
match ret {
CPlace::NoPlace(_layout) => {}
CPlace::Var(var, layout) => {
let clif_ty = fx.clif_type(layout.ty).unwrap();
let val = match clif_ty {
types::I8 | types::I16 | types::I32 | types::I64 => fx.bcx.ins().iconst(clif_ty, 0),
types::F32 => {
let zero = fx.bcx.ins().iconst(types::I32, 0);
fx.bcx.ins().bitcast(types::F32, zero)
}
types::F64 => {
let zero = fx.bcx.ins().iconst(types::I64, 0);
fx.bcx.ins().bitcast(types::F64, zero)
}
_ => panic!("clif_type returned {}", clif_ty),
};
fx.bcx.def_var(mir_var(var), val);
}
_ => {
let addr = ret.to_addr(fx);
let layout = ret.layout();
fx.bcx.emit_small_memset(fx.module.target_config(), addr, 0, layout.size.bytes(), 1);
}
}
};
write_bytes, (c dst, v val, v count) {
let pointee_ty = dst.layout().ty.builtin_deref(true).unwrap().ty;
@ -356,6 +376,11 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
fx.bcx.call_memset(fx.module.target_config(), dst_ptr, val, count);
};
uninit, <T> () {
if ret.layout().abi == Abi::Uninhabited {
crate::trap::trap_panic(&mut fx.bcx);
return;
}
let uninit_place = CPlace::new_stack_slot(fx, T);
let uninit_val = uninit_place.to_cvalue(fx);
ret.write_cvalue(fx, uninit_val);