1
Fork 0

Merge commit '9a0c32934e' into sync_cg_clif-2021-03-05

This commit is contained in:
bjorn3 2021-03-05 19:12:59 +01:00
commit 7a6ea77473
73 changed files with 1145 additions and 2596 deletions

View file

@ -13,19 +13,18 @@ use crate::prelude::*;
/// in an upcast, where the new vtable for an object will be derived
/// from the old one.
pub(crate) fn unsized_info<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
source: Ty<'tcx>,
target: Ty<'tcx>,
old_info: Option<Value>,
) -> Value {
let (source, target) =
fx.tcx
.struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all());
fx.tcx.struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all());
match (&source.kind(), &target.kind()) {
(&ty::Array(_, len), &ty::Slice(_)) => fx.bcx.ins().iconst(
fx.pointer_type,
len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64,
),
(&ty::Array(_, len), &ty::Slice(_)) => fx
.bcx
.ins()
.iconst(fx.pointer_type, len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64),
(&ty::Dynamic(..), &ty::Dynamic(..)) => {
// For now, upcasts are limited to changes in marker
// traits, and hence never actually require an actual
@ -35,17 +34,13 @@ pub(crate) fn unsized_info<'tcx>(
(_, &ty::Dynamic(ref data, ..)) => {
crate::vtable::get_vtable(fx, fx.layout_of(source), data.principal())
}
_ => bug!(
"unsized_info: invalid unsizing {:?} -> {:?}",
source,
target
),
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
}
}
/// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer.
fn unsize_thin_ptr<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
src: Value,
src_layout: TyAndLayout<'tcx>,
dst_layout: TyAndLayout<'tcx>,
@ -89,24 +84,22 @@ fn unsize_thin_ptr<'tcx>(
/// Coerce `src`, which is a reference to a value of type `src_ty`,
/// to a value of type `dst_ty` and store the result in `dst`
pub(crate) fn coerce_unsized_into<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
src: CValue<'tcx>,
dst: CPlace<'tcx>,
) {
let src_ty = src.layout().ty;
let dst_ty = dst.layout().ty;
let mut coerce_ptr = || {
let (base, info) = if fx
.layout_of(src.layout().ty.builtin_deref(true).unwrap().ty)
.is_unsized()
{
// fat-ptr to fat-ptr unsize preserves the vtable
// i.e., &'a fmt::Debug+Send => &'a fmt::Debug
src.load_scalar_pair(fx)
} else {
let base = src.load_scalar(fx);
unsize_thin_ptr(fx, base, src.layout(), dst.layout())
};
let (base, info) =
if fx.layout_of(src.layout().ty.builtin_deref(true).unwrap().ty).is_unsized() {
// fat-ptr to fat-ptr unsize preserves the vtable
// i.e., &'a fmt::Debug+Send => &'a fmt::Debug
src.load_scalar_pair(fx)
} else {
let base = src.load_scalar(fx);
unsize_thin_ptr(fx, base, src.layout(), dst.layout())
};
dst.write_cvalue(fx, CValue::by_val_pair(base, info, dst.layout()));
};
match (&src_ty.kind(), &dst_ty.kind()) {
@ -131,39 +124,26 @@ pub(crate) fn coerce_unsized_into<'tcx>(
}
}
}
_ => bug!(
"coerce_unsized_into: invalid coercion {:?} -> {:?}",
src_ty,
dst_ty
),
_ => bug!("coerce_unsized_into: invalid coercion {:?} -> {:?}", src_ty, dst_ty),
}
}
// Adapted from https://github.com/rust-lang/rust/blob/2a663555ddf36f6b041445894a8c175cd1bc718c/src/librustc_codegen_ssa/glue.rs
pub(crate) fn size_and_align_of_dst<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
layout: TyAndLayout<'tcx>,
info: Value,
) -> (Value, Value) {
if !layout.is_unsized() {
let size = fx
.bcx
.ins()
.iconst(fx.pointer_type, layout.size.bytes() as i64);
let align = fx
.bcx
.ins()
.iconst(fx.pointer_type, layout.align.abi.bytes() as i64);
let size = fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64);
let align = fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64);
return (size, align);
}
match layout.ty.kind() {
ty::Dynamic(..) => {
// load size/align from vtable
(
crate::vtable::size_of_obj(fx, info),
crate::vtable::min_align_of_obj(fx, info),
)
(crate::vtable::size_of_obj(fx, info), crate::vtable::min_align_of_obj(fx, info))
}
ty::Slice(_) | ty::Str => {
let unit = layout.field(fx, 0);
@ -171,9 +151,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
// times the unit size.
(
fx.bcx.ins().imul_imm(info, unit.size.bytes() as i64),
fx.bcx
.ins()
.iconst(fx.pointer_type, unit.align.abi.bytes() as i64),
fx.bcx.ins().iconst(fx.pointer_type, unit.align.abi.bytes() as i64),
)
}
_ => {
@ -211,10 +189,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
// Choose max of two known alignments (combined value must
// be aligned according to more restrictive of the two).
let cmp = fx
.bcx
.ins()
.icmp(IntCC::UnsignedGreaterThan, sized_align, unsized_align);
let cmp = fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, sized_align, unsized_align);
let align = fx.bcx.ins().select(cmp, sized_align, unsized_align);
// Issue #27023: must add any necessary padding to `size`