Better monomorphization

This commit is contained in:
bjorn3 2018-06-24 14:01:41 +02:00
parent 0479604be1
commit f62381865f
3 changed files with 41 additions and 40 deletions

@ -150,13 +150,13 @@ fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &mut
}); // Dummy stack slot for debugging
let func_params = mir.args_iter().map(|local| {
let layout = fx.tcx.layout_of(ParamEnv::reveal_all().and(fx.monomorphize(&mir.local_decls[local].ty))).unwrap();
let layout = fx.layout_of(mir.local_decls[local].ty);
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
kind: StackSlotKind::ExplicitSlot,
size: layout.size.bytes() as u32,
offset: None,
});
let ty = cton_type_from_ty(mir.local_decls[local].ty);
let ty = fx.cton_type(mir.local_decls[local].ty);
(local, fx.bcx.append_ebb_param(start_ebb, ty.unwrap_or(types::I64)), ty, stack_slot)
}).collect::<Vec<(Local, Value, Option<Type>, StackSlot)>>();
@ -174,7 +174,7 @@ fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &mut
}
for local in mir.vars_and_temps_iter() {
let layout = cx.tcx.layout_of(ParamEnv::reveal_all().and(mir.local_decls[local].ty)).unwrap();
let layout = fx.layout_of(mir.local_decls[local].ty);
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
kind: StackSlotKind::ExplicitSlot,
size: layout.size.bytes() as u32,
@ -243,7 +243,7 @@ fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &mut
.map(|arg| {
let ty = arg.ty(&fx.mir.local_decls, fx.tcx);
let arg = trans_operand(fx, arg);
if let Some(_) = cton_type_from_ty(ty) {
if let Some(_) = fx.cton_type(ty) {
arg.load_value(fx, ty)
} else {
arg.force_stack(fx, ty)
@ -416,9 +416,10 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, stmt: &Statement<'tcx
lval.write_cvalue(fx, operand, &dest_ty);
}
Rvalue::Discriminant(place) => {
let dest_cton_ty = fx.cton_type(&dest_ty).unwrap();
let place_ty = fx.monomorphize(&place.ty(&fx.mir.local_decls, fx.tcx).to_ty(fx.tcx));
let cton_place_ty = cton_type_from_ty(&place_ty);
let layout = fx.tcx.layout_of(ParamEnv::reveal_all().and(place_ty)).unwrap();
let cton_place_ty = fx.cton_type(&place_ty);
let layout = fx.layout_of(place_ty);
if layout.abi == layout::Abi::Uninhabited {
fx.bcx.ins().trap(TrapCode::User(!0));
@ -457,11 +458,11 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, stmt: &Statement<'tcx
niche_start,
..
} => {
let niche_llty = cton_type_from_ty(discr_ty).unwrap();
let niche_llty = fx.cton_type(discr_ty).unwrap();
if niche_variants.start() == niche_variants.end() {
let b = fx.bcx.ins().icmp_imm(IntCC::Equal, lldiscr, niche_start as u64 as i64);
let if_true = fx.bcx.ins().iconst(cton_type_from_ty(&dest_ty).unwrap(), *niche_variants.start() as u64 as i64);
let if_false = fx.bcx.ins().iconst(cton_type_from_ty(&dest_ty).unwrap(), dataful_variant as u64 as i64);
let if_true = fx.bcx.ins().iconst(dest_cton_ty, *niche_variants.start() as u64 as i64);
let if_false = fx.bcx.ins().iconst(dest_cton_ty, dataful_variant as u64 as i64);
let val = fx.bcx.ins().select(b, if_true, if_false);
lval.write_cvalue(fx, CValue::ByVal(val), &dest_ty);
} else {
@ -520,16 +521,18 @@ fn trans_operand<'a, 'tcx>(fx: &mut FunctionCx<'a, 'tcx>, operand: &Operand<'tcx
Operand::Constant(const_) => {
match const_.literal {
Literal::Value { value } => {
let layout = fx.tcx.layout_of(ParamEnv::empty().and(const_.ty)).unwrap();
let layout = fx.layout_of(const_.ty);
match const_.ty.sty {
TypeVariants::TyUint(_) => {
let bits = value.to_scalar().unwrap().to_bits(layout.size).unwrap();
let iconst = fx.bcx.ins().iconst(cton_type_from_ty(const_.ty).unwrap(), bits as u64 as i64);
let cton_ty = fx.cton_type(const_.ty).unwrap();
let iconst = fx.bcx.ins().iconst(cton_ty, bits as u64 as i64);
CValue::ByVal(iconst)
}
TypeVariants::TyInt(_) => {
let bits = value.to_scalar().unwrap().to_bits(layout.size).unwrap();
let iconst = fx.bcx.ins().iconst(cton_type_from_ty(const_.ty).unwrap(), bits as i128 as i64);
let cton_ty = fx.cton_type(const_.ty).unwrap();
let iconst = fx.bcx.ins().iconst(cton_ty, bits as i128 as i64);
CValue::ByVal(iconst)
}
TypeVariants::TyFnDef(def_id, substs) => {

@ -19,7 +19,7 @@ impl EntityRef for Variable {
}
}
pub fn cton_type_from_ty(ty: Ty) -> Option<types::Type> {
fn cton_type_from_ty(ty: Ty) -> Option<types::Type> {
Some(match ty.sty {
TypeVariants::TyBool => types::I8,
TypeVariants::TyUint(size) => {
@ -56,22 +56,6 @@ pub fn fixup_cton_ty(ty: Type) -> Type {
}
}
pub fn extend_val<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, val: Value, ty: Ty) -> Value {
let cton_ty = cton_type_from_ty(ty).unwrap();
let to_ty = match cton_ty {
types::I64 => return val,
types::I32 => return val,
_ => types::I32,
};
match ty.sty {
TypeVariants::TyBool => fx.bcx.ins().uextend(to_ty, val),
TypeVariants::TyUint(_) => fx.bcx.ins().uextend(to_ty, val),
TypeVariants::TyInt(_) => fx.bcx.ins().sextend(to_ty, val),
TypeVariants::TyFnPtr(_) => val,
_ => unimplemented!(),
}
}
// FIXME(cretonne) fix load.i8
fn load_workaround(fx: &mut FunctionCx, ty: Type, addr: Value, offset: i32) -> Value {
use cretonne::codegen::ir::types::*;
@ -106,7 +90,7 @@ impl CValue {
match self {
CValue::ByRef(value) => value,
CValue::ByVal(value) => {
let layout = fx.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
let layout = fx.layout_of(ty);
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
kind: StackSlotKind::ExplicitSlot,
size: layout.size.bytes() as u32,
@ -125,7 +109,7 @@ impl CValue {
pub fn load_value<'a, 'tcx: 'a>(self, fx: &mut FunctionCx<'a, 'tcx>, ty: Ty<'tcx>) -> Value {
match self {
CValue::ByRef(value) => {
let cton_ty = cton_type_from_ty(fx.monomorphize(&ty)).expect(&format!("{:?}", ty));
let cton_ty = fx.cton_type(ty).expect(&format!("{:?}", ty));
load_workaround(fx, cton_ty, value, 0)
}
CValue::ByVal(value) => value,
@ -148,7 +132,7 @@ impl CValue {
CValue::ByRef(addr) => addr,
_ => bug!("place_field for {:?}", self),
};
let layout = fx.tcx.layout_of(ParamEnv::empty().and(fx.monomorphize(&ty))).unwrap();
let layout = fx.layout_of(ty);
let field_offset = layout.fields.offset(field.index());
if field_offset.bytes() > 0 {
let field_offset = fx.bcx.ins().iconst(types::I64, field_offset.bytes() as i64);
@ -159,8 +143,8 @@ impl CValue {
}
pub fn const_val<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, ty: Ty<'tcx>, const_val: i64) -> CValue {
let ty = fx.monomorphize(&ty);
CValue::ByVal(fx.bcx.ins().iconst(cton_type_from_ty(ty).unwrap(), const_val))
let ty = fx.cton_type(ty).unwrap();
CValue::ByVal(fx.bcx.ins().iconst(ty, const_val))
}
}
@ -190,7 +174,7 @@ impl<'a, 'tcx: 'a> CPlace {
}
pub fn write_cvalue(self, fx: &mut FunctionCx<'a, 'tcx>, from: CValue, ty: Ty<'tcx>) {
let layout = fx.tcx.layout_of(ParamEnv::reveal_all().and(fx.monomorphize(&ty))).unwrap();
let layout = fx.layout_of(ty);
let size = layout.size.bytes() as i32;
match self {
CPlace::Var(var) => {
@ -198,7 +182,7 @@ impl<'a, 'tcx: 'a> CPlace {
fx.bcx.def_var(var, data)
},
CPlace::Addr(addr) => {
if let Some(cton_ty) = cton_type_from_ty(ty) {
if let Some(cton_ty) = fx.cton_type(ty) {
let data = from.load_value(fx, ty);
store_workaround(fx, cton_ty, addr, data, 0);
} else {
@ -214,7 +198,7 @@ impl<'a, 'tcx: 'a> CPlace {
pub fn place_field(self, fx: &mut FunctionCx<'a, 'tcx>, field: mir::Field, ty: Ty<'tcx>) -> (CPlace, layout::TyLayout<'tcx>) {
let base = self.expect_addr();
let layout = fx.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
let layout = fx.layout_of(ty);
let field_offset = layout.fields.offset(field.index());
if field_offset.bytes() > 0 {
let field_offset = fx.bcx.ins().iconst(types::I64, field_offset.bytes() as i64);
@ -255,8 +239,8 @@ pub fn cton_sig_from_mono_fn_sig<'a ,'tcx: 'a>(sig: PolyFnSig<'tcx>) -> Signatur
}
pub fn cton_intcast<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, val: Value, from: Ty<'tcx>, to: Ty<'tcx>, signed: bool) -> Value {
let from = cton_type_from_ty(from).unwrap();
let to = cton_type_from_ty(to).unwrap();
let from = fx.cton_type(from).unwrap();
let to = fx.cton_type(to).unwrap();
if from == to {
return val;
}
@ -283,6 +267,16 @@ pub struct FunctionCx<'a, 'tcx: 'a> {
pub local_map: HashMap<Local, CPlace>,
}
impl<'a, 'tcx: 'a> LayoutOf for &'a FunctionCx<'a, 'tcx> {
type Ty = Ty<'tcx>;
type TyLayout = TyLayout<'tcx>;
fn layout_of(self, ty: Ty<'tcx>) -> TyLayout<'tcx> {
let ty = self.monomorphize(&ty);
self.tcx.layout_of(ParamEnv::reveal_all().and(&ty)).unwrap()
}
}
impl<'f, 'tcx> FunctionCx<'f, 'tcx> {
pub fn monomorphize<T>(&self, value: &T) -> T
where T: TypeFoldable<'tcx>
@ -294,6 +288,10 @@ impl<'f, 'tcx> FunctionCx<'f, 'tcx> {
)
}
pub fn cton_type(&self, ty: Ty<'tcx>) -> Option<Type> {
cton_type_from_ty(self.monomorphize(&ty))
}
pub fn get_ebb(&self, bb: BasicBlock) -> Ebb {
*self.ebb_map.get(&bb).unwrap()
}

@ -42,7 +42,7 @@ mod prelude {
pub use rustc::mir;
pub use rustc::mir::*;
pub use rustc::session::Session;
pub use rustc::ty::layout;
pub use rustc::ty::layout::{self, LayoutOf, TyLayout};
pub use rustc::ty::{
self, subst::Substs, FnSig, Instance, InstanceDef, ParamEnv, PolyFnSig, Ty, TyCtxt,
TypeFoldable, TypeVariants,