diff --git a/cilly/src/cil_node.rs b/cilly/src/cil_node.rs index b854396b..66c8d270 100644 --- a/cilly/src/cil_node.rs +++ b/cilly/src/cil_node.rs @@ -224,6 +224,33 @@ pub enum CILNode { } impl CILNode { + pub fn ovf_check_tuple( + asm: &mut Assembly, + tuple: ClassRefIdx, + out_of_range: Self, + val: Self, + tpe: Type, + ) -> CILNode { + let item2 = asm.alloc_string("Item2"); + let item1 = asm.alloc_string("Item1"); + CILNode::TemporaryLocal(Box::new(( + asm.alloc_type(tuple), + [ + CILRoot::SetField { + addr: Box::new(CILNode::LoadAddresOfTMPLocal), + value: Box::new(out_of_range), + desc: asm.alloc_field(crate::FieldDesc::new(tuple, item2, Type::Bool)), + }, + CILRoot::SetField { + addr: Box::new(CILNode::LoadAddresOfTMPLocal), + value: Box::new(val), + desc: asm.alloc_field(crate::FieldDesc::new(tuple, item1, tpe)), + }, + ] + .into(), + CILNode::LoadTMPLocal, + ))) + } pub fn create_slice( slice_tpe: ClassRefIdx, diff --git a/cilly/src/method.rs b/cilly/src/method.rs index e67df6f0..68b7deab 100644 --- a/cilly/src/method.rs +++ b/cilly/src/method.rs @@ -67,54 +67,6 @@ impl Method { .nodes() .any(|node| matches!(node, CILNode::LDLocA(loc) if *loc == local)) } - /// For a `local`, returns the *values* of all its assigements. This *will not include the root, only the nodes*! - /// WARNING: this ONLY works on "finalized" CIL, and DOES NOT SUPPORT SUBTREES - pub fn local_sets(&self, local: u32) -> impl Iterator { - { - let this = &self; - this.blocks() - .iter() - .flat_map(|block| block.iter_tree_roots()) - } - .filter_map(move |root| match root { - CILRoot::STLoc { local: loc, tree } if (*loc == local) => Some(tree), - _ => None, - }) - } - pub fn direct_set_count(&self, local: u32) -> usize { - self.local_sets(local).count() - } - pub fn const_opt_pass(&mut self) { - use crate::cil_iter_mut::CILIterMutTrait; - // If a local is set only once, and its address is never taken, it is likely to be const - // TODO: this is inefficient Consider checking all locals at once? - let luo = LocalUsageInfo::from_method(self); - let locals_address_not_taken: Box<[_]> = (0..(self.locals().len())) - .filter(|idx| !luo.is_address_taken(*idx)) - .collect(); - - for local in locals_address_not_taken { - let sets = self.local_sets(local as u32); - if let Some(val) = all_evals_identical(sets) { - let mut tmp: Vec<_> = self - .blocks - .iter_mut() - .flat_map(|block| block.all_trees_mut()) - .map(|tree| tree.root_mut()) - .collect(); - - tmp.iter_mut() - .flat_map(|tree| tree.deref_mut().into_iter().nodes()) - .for_each(|node| match node { - CILNode::LDLoc(loc) if *loc == local as u32 => *node = val.clone(), - CILNode::LDLocA(loc) if *loc == local as u32 => { - panic!("const propagation failed: the address of const taken") - } - _ => (), - }); - } - } - } /// Iterates over each `CILNode` and `CILRoot`. pub fn iter_cil(&self) -> impl Iterator { diff --git a/src/binop/checked/mod.rs b/src/binop/checked/mod.rs index 20a3cd32..dee6e915 100644 --- a/src/binop/checked/mod.rs +++ b/src/binop/checked/mod.rs @@ -11,26 +11,7 @@ use rustc_middle::ty::{IntTy, Ty, TyKind, UintTy}; pub fn result_tuple(tpe: Type, out_of_range: CILNode, val: CILNode, asm: &mut Assembly) -> CILNode { let tuple = crate::r#type::simple_tuple(&[tpe, Type::Bool], asm); - let item2 = asm.alloc_string("Item2"); - let item1 = asm.alloc_string("Item1"); - CILNode::TemporaryLocal(Box::new(( - asm.alloc_type(tuple), - [ - CILRoot::SetField { - addr: Box::new(CILNode::LoadAddresOfTMPLocal), - value: Box::new(out_of_range), - desc: asm.alloc_field(FieldDesc::new(tuple, item2, Type::Bool)), - }, - CILRoot::SetField { - addr: Box::new(CILNode::LoadAddresOfTMPLocal), - value: Box::new(val), - desc: asm.alloc_field(FieldDesc::new(tuple, item1, tpe)), - }, - ] - .into(), - CILNode::LoadTMPLocal, - ))) - //CILNode::T + CILNode::ovf_check_tuple(asm, tuple, out_of_range, val, tpe) } pub fn zero(ty: Ty, asm: &mut Assembly) -> CILNode { match ty.kind() { diff --git a/src/constant.rs b/src/constant.rs index 7b29044c..a13f7cbf 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -238,18 +238,12 @@ fn load_const_scalar<'tcx>( if matches!(scalar_type, Type::Ptr(_) | Type::FnPtr(_)) { return load_scalar_ptr(ctx, ptr).cast_ptr(scalar_type); } - let uint8_ptr = ctx.nptr(Type::Int(Int::U8)); - return CILNode::LdObj { - obj: Box::new(scalar_type), - ptr: Box::new(CILNode::TemporaryLocal(Box::new(( - ctx.alloc_type(uint8_ptr), - [CILRoot::SetTMPLocal { - value: load_scalar_ptr(ctx, ptr), - }] - .into(), - CILNode::LoadAddresOfTMPLocal.cast_ptr(ctx.nptr(scalar_type)), - )))), - }; + return CILNode::transmute_on_stack( + load_scalar_ptr(ctx, ptr), + ctx.nptr(Type::Int(Int::U8)), + scalar_type, + ctx, + ); } }; @@ -265,30 +259,17 @@ fn load_const_scalar<'tcx>( TyKind::Tuple(elements) => { if elements.is_empty() { let scalar_ptr = ctx.nptr(scalar_type); - CILNode::TemporaryLocal(Box::new(( - ctx.alloc_type(scalar_ptr), - [].into(), - CILNode::LdObj { - ptr: CILNode::LoadTMPLocal.into(), - obj: Type::Void.into(), - }, - ))) + CILNode::uninit_val(scalar_ptr, ctx) } else { - CILNode::LdObj { - ptr: Box::new( - CILNode::PointerToConstValue(Box::new(scalar_u128)) - .cast_ptr(ctx.nptr(scalar_type)), - ), - obj: scalar_type.into(), - } + CILNode::V2(ctx.alloc_node(scalar_u128)).transmute_on_stack( + Type::Int(Int::U128), + scalar_type, + ctx, + ) } } - TyKind::Adt(_, _) | TyKind::Closure(_, _) => CILNode::LdObj { - ptr: Box::new( - CILNode::PointerToConstValue(Box::new(scalar_u128)).cast_ptr(ctx.nptr(scalar_type)), - ), - obj: scalar_type.into(), - }, + TyKind::Adt(_, _) | TyKind::Closure(_, _) => CILNode::V2(ctx.alloc_node(scalar_u128)) + .transmute_on_stack(Type::Int(Int::U128), scalar_type, ctx), TyKind::Char => CILNode::V2(ctx.alloc_node(u32::try_from(scalar_u128).unwrap())), _ => todo!("Can't load scalar constants of type {scalar_ty:?}!"), } diff --git a/src/place/adress.rs b/src/place/adress.rs index 7a021c8a..b136ae4e 100644 --- a/src/place/adress.rs +++ b/src/place/adress.rs @@ -7,7 +7,6 @@ use crate::{ use cilly::{ call, cil_node::CILNode, - cil_root::CILRoot, conv_usize, ld_field, v2::{cilnode::MethodKind, FieldDesc, Int, MethodRef}, Const, IntoAsmIndex, Type, diff --git a/src/rvalue.rs b/src/rvalue.rs index 98c4c843..b283afe6 100644 --- a/src/rvalue.rs +++ b/src/rvalue.rs @@ -506,15 +506,7 @@ fn ptr_to_ptr<'tcx>( let target_fat = pointer_to_is_fat(*target_pointed_to, ctx.tcx(), ctx.instance()); match (src_fat, target_fat) { (true, true) => { - let parrent = handle_operand(operand, ctx); - - let target_ptr = ctx.nptr(target_type); - let tmp = CILNode::TemporaryLocal(Box::new(( - ctx.alloc_type(source_type), - [CILRoot::SetTMPLocal { value: parrent }].into(), - Box::new(CILNode::LoadAddresOfTMPLocal).cast_ptr(target_ptr), - ))); - crate::place::deref_op(crate::place::PlaceTy::Ty(target), ctx, tmp) + CILNode::transmute_on_stack(handle_operand(operand, ctx), source_type, target_type, ctx) } (true, false) => { let field_desc = FieldDesc::new( @@ -522,15 +514,8 @@ fn ptr_to_ptr<'tcx>( ctx.alloc_string(crate::DATA_PTR), ctx.nptr(cilly::v2::Type::Void), ); - CILNode::TemporaryLocal(Box::new(( - ctx.alloc_type(source_type), - [CILRoot::SetTMPLocal { - value: handle_operand(operand, ctx), - }] - .into(), - ld_field!(CILNode::LoadAddresOfTMPLocal, ctx.alloc_field(field_desc)) - .cast_ptr(target_type), - ))) + ld_field!(operand_address(operand, ctx), ctx.alloc_field(field_desc)) + .cast_ptr(target_type) } (false, true) => { panic!("ERROR: a non-unsizing cast turned a sized ptr into an unsized one")