diff --git a/src/analyze.rs b/src/analyze.rs index 3bebf0ed7772..c5541b152573 100644 --- a/src/analyze.rs +++ b/src/analyze.rs @@ -23,7 +23,7 @@ pub fn analyze(fx: &FunctionCx<'_, '_, impl Backend>) -> IndexVec match &place_and_rval.1 { Rvalue::Ref(_, _, place) => { - analyze_non_ssa_place(&mut flag_map, place); + not_ssa(&mut flag_map, place.local) } _ => {} }, @@ -36,7 +36,7 @@ pub fn analyze(fx: &FunctionCx<'_, '_, impl Backend>) -> IndexVec) -> IndexVec, place: &Place) { - match place.base { - PlaceBase::Local(local) => not_ssa(flag_map, local), - _ => {} - } -} - fn not_ssa(flag_map: &mut IndexVec, local: Local) { flag_map[local] = SsaKind::NotSsa; } diff --git a/src/base.rs b/src/base.rs index db10443df1e3..0c0f43d076e3 100644 --- a/src/base.rs +++ b/src/base.rs @@ -292,7 +292,7 @@ fn trans_stmt<'tcx>( fx.set_debug_loc(stmt.source_info); - #[cfg(debug_assertions)] + #[cfg(false_debug_assertions)] match &stmt.kind { StatementKind::StorageLive(..) | StatementKind::StorageDead(..) => {} // Those are not very useful _ => { @@ -646,20 +646,7 @@ pub fn trans_place<'tcx>( fx: &mut FunctionCx<'_, 'tcx, impl Backend>, place: &Place<'tcx>, ) -> CPlace<'tcx> { - let mut cplace = match &place.base { - PlaceBase::Local(local) => fx.get_local_place(*local), - PlaceBase::Static(static_) => match static_.kind { - StaticKind::Static => { - // Statics can't be generic, so `static_.ty` doesn't need to be monomorphized. - crate::constant::codegen_static_ref(fx, static_.def_id, static_.ty) - } - StaticKind::Promoted(promoted, substs) => { - let instance = Instance::new(static_.def_id, fx.monomorphize(&substs)); - let ty = fx.monomorphize(&static_.ty); - crate::constant::trans_promoted(fx, instance, promoted, ty) - } - }, - }; + let mut cplace = fx.get_local_place(place.local); for elem in &*place.projection { match *elem { diff --git a/src/constant.rs b/src/constant.rs index 686147aa594b..92ccaa1b1646 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -40,7 +40,7 @@ pub fn codegen_static(constants_cx: &mut ConstantCx, def_id: DefId) { constants_cx.todo.insert(TodoItem::Static(def_id)); } -pub fn codegen_static_ref<'tcx>( +fn codegen_static_ref<'tcx>( fx: &mut FunctionCx<'_, 'tcx, impl Backend>, def_id: DefId, ty: Ty<'tcx>, @@ -50,31 +50,37 @@ pub fn codegen_static_ref<'tcx>( cplace_for_dataid(fx, ty, data_id) } -pub fn trans_promoted<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Backend>, - instance: Instance<'tcx>, - promoted: Promoted, - dest_ty: Ty<'tcx>, -) -> CPlace<'tcx> { - match fx.tcx.const_eval_promoted(instance, promoted) { - Ok(const_) => { - let cplace = trans_const_place(fx, const_); - debug_assert_eq!(cplace.layout(), fx.layout_of(dest_ty)); - cplace - } - Err(_) => crate::trap::trap_unreachable_ret_place( - fx, - fx.layout_of(dest_ty), - "[panic] Tried to get value of promoted value with errored during const eval.", - ), - } -} - pub fn trans_constant<'tcx>( fx: &mut FunctionCx<'_, 'tcx, impl Backend>, constant: &Constant<'tcx>, ) -> CValue<'tcx> { - let const_ = force_eval_const(fx, &constant.literal); + let const_ = match constant.literal.val { + ConstKind::Unevaluated(def_id, ref substs, promoted) if fx.tcx.is_static(def_id) => { + assert!(substs.is_empty()); + assert!(promoted.is_none()); + + return codegen_static_ref( + fx, + def_id, + fx.monomorphize(&constant.literal.ty), + ).to_cvalue(fx); + } + ConstKind::Unevaluated(def_id, ref substs, promoted) => { + let substs = fx.monomorphize(substs); + fx.tcx.const_eval_resolve( + ParamEnv::reveal_all(), + def_id, + substs, + promoted, + None, // FIXME use correct span + ).unwrap_or_else(|_| { + fx.tcx.sess.abort_if_errors(); + unreachable!(); + }) + } + _ => fx.monomorphize(&constant.literal), + }; + trans_const_value(fx, const_) } @@ -83,9 +89,15 @@ pub fn force_eval_const<'tcx>( const_: &'tcx Const, ) -> &'tcx Const<'tcx> { match const_.val { - ConstKind::Unevaluated(def_id, ref substs) => { + ConstKind::Unevaluated(def_id, ref substs, promoted) => { let substs = fx.monomorphize(substs); - fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def_id, substs, None).unwrap_or_else(|_| { + fx.tcx.const_eval_resolve( + ParamEnv::reveal_all(), + def_id, + substs, + promoted, + None, // FIXME pass correct span + ).unwrap_or_else(|_| { fx.tcx.sess.abort_if_errors(); unreachable!(); }) @@ -100,38 +112,78 @@ pub fn trans_const_value<'tcx>( ) -> CValue<'tcx> { let ty = fx.monomorphize(&const_.ty); let layout = fx.layout_of(ty); - match ty.kind { - ty::Bool | ty::Uint(_) => { - let bits = const_.val.try_to_bits(layout.size).unwrap(); - CValue::const_val(fx, ty, bits) + + if layout.is_zst() { + return CValue::by_ref( + crate::Pointer::const_addr(fx, i64::try_from(layout.align.pref.bytes()).unwrap()), + layout, + ); + } + + let const_val = match const_.val { + ConstKind::Value(const_val) => const_val, + _ => unreachable!("Const {:?} should have been evaluated", const_), + }; + + match const_val { + ConstValue::Scalar(x) => { + let scalar = match layout.abi { + layout::Abi::Scalar(ref x) => x, + _ => bug!("from_const: invalid ByVal layout: {:#?}", layout), + }; + + match ty.kind { + ty::Bool | ty::Uint(_) => { + let bits = const_.val.try_to_bits(layout.size).unwrap_or_else(|| { + panic!("{:?}\n{:?}", const_, layout); + }); + CValue::const_val(fx, ty, bits) + } + ty::Int(_) => { + let bits = const_.val.try_to_bits(layout.size).unwrap(); + CValue::const_val( + fx, + ty, + rustc::mir::interpret::sign_extend(bits, layout.size), + ) + } + ty::Float(fty) => { + let bits = const_.val.try_to_bits(layout.size).unwrap(); + let val = match fty { + FloatTy::F32 => fx + .bcx + .ins() + .f32const(Ieee32::with_bits(u32::try_from(bits).unwrap())), + FloatTy::F64 => fx + .bcx + .ins() + .f64const(Ieee64::with_bits(u64::try_from(bits).unwrap())), + }; + CValue::by_val(val, layout) + } + ty::FnDef(_def_id, _substs) => CValue::by_ref( + crate::pointer::Pointer::const_addr(fx, fx.pointer_type.bytes() as i64), + layout, + ), + _ => trans_const_place(fx, const_).to_cvalue(fx), + } } - ty::Int(_) => { - let bits = const_.val.try_to_bits(layout.size).unwrap(); - CValue::const_val( - fx, - ty, - rustc::mir::interpret::sign_extend(bits, layout.size), + ConstValue::ByRef { alloc, offset } => { + let alloc_id = fx.tcx.alloc_map.lock().create_memory_alloc(alloc); + fx.constants_cx.todo.insert(TodoItem::Alloc(alloc_id)); + let data_id = data_id_for_alloc_id(fx.module, alloc_id, alloc.align); + let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + let global_ptr = fx.bcx.ins().global_value(fx.pointer_type, local_data_id); + assert!(!layout.is_unsized(), "unsized ConstValue::ByRef not supported"); + CValue::by_ref( + crate::pointer::Pointer::new(global_ptr) + .offset_i64(fx, i64::try_from(offset.bytes()).unwrap()), + layout, ) } - ty::Float(fty) => { - let bits = const_.val.try_to_bits(layout.size).unwrap(); - let val = match fty { - FloatTy::F32 => fx - .bcx - .ins() - .f32const(Ieee32::with_bits(u32::try_from(bits).unwrap())), - FloatTy::F64 => fx - .bcx - .ins() - .f64const(Ieee64::with_bits(u64::try_from(bits).unwrap())), - }; - CValue::by_val(val, layout) + ConstValue::Slice { data: _, start: _, end: _ } => { + trans_const_place(fx, const_).to_cvalue(fx) } - ty::FnDef(_def_id, _substs) => CValue::by_ref( - crate::pointer::Pointer::const_addr(fx, fx.pointer_type.bytes() as i64), - layout, - ), - _ => trans_const_place(fx, const_).to_cvalue(fx), } } @@ -480,22 +532,8 @@ pub fn mir_operand_get_const_val<'tcx>( fx: &FunctionCx<'_, 'tcx, impl Backend>, operand: &Operand<'tcx>, ) -> Option<&'tcx Const<'tcx>> { - let place = match operand { - Operand::Copy(place) | Operand::Move(place) => place, + match operand { + Operand::Copy(_) | Operand::Move(_) => return None, Operand::Constant(const_) => return Some(force_eval_const(fx, const_.literal)), - }; - - assert!(place.projection.is_empty()); - let static_ = match &place.base { - PlaceBase::Static(static_) => static_, - PlaceBase::Local(_) => return None, - }; - - Some(match &static_.kind { - StaticKind::Static => unimplemented!(), - StaticKind::Promoted(promoted, substs) => { - let instance = Instance::new(static_.def_id, fx.monomorphize(substs)); - fx.tcx.const_eval_promoted(instance, *promoted).unwrap() - } - }) + } } diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 4fa3570d2fd7..d4be26885a04 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -283,7 +283,7 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> { &local_map, &value_labels_ranges, Place { - base: PlaceBase::Local(local), + local, projection: ty::List::empty(), }, ); @@ -305,12 +305,8 @@ fn place_location<'a, 'tcx>( place: Place<'tcx>, ) -> AttributeValue { assert!(place.projection.is_empty()); // FIXME implement them - let cplace = match place.base { - PlaceBase::Local(local) => local_map[&local], - PlaceBase::Static(_) => bug!("Unenforced invariant that the place is based on a Local violated: {:?}", place), - }; - match cplace.inner() { + match local_map[&place.local].inner() { CPlaceInner::Var(local) => { let value_label = cranelift_codegen::ir::ValueLabel::from_u32(local.as_u32()); if let Some(value_loc_ranges) = value_labels_ranges.get(&value_label) { diff --git a/src/trap.rs b/src/trap.rs index e297b27debb3..316a26781dab 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -93,15 +93,3 @@ pub fn trap_unreachable_ret_value<'tcx>( trap_unimplemented(fx, msg); CValue::by_ref(Pointer::const_addr(fx, 0), dest_layout) } - -/// Like `trap_unreachable` but returns a fake place for the specified type. -/// -/// Trap code: user65535 -pub fn trap_unreachable_ret_place<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>, - dest_layout: TyLayout<'tcx>, - msg: impl AsRef, -) -> CPlace<'tcx> { - trap_unimplemented(fx, msg); - CPlace::for_ptr(Pointer::const_addr(fx, 0), dest_layout) -}