Better monomorphization
This commit is contained in:
parent
0479604be1
commit
f62381865f
27
src/base.rs
27
src/base.rs
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user