From 89e6a67310a6d733895fb47937293c34bd464266 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 5 Jan 2024 17:19:18 +0000 Subject: [PATCH] Const prop doesn't need a stack anymore --- .../rustc_mir_transform/src/const_prop.rs | 22 ++++------ .../src/const_prop_lint.rs | 44 ++++++------------- 2 files changed, 22 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index c5824c307702..a517997c1eb9 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -49,24 +49,18 @@ pub(crate) macro throw_machine_stop_str($($tt:tt)*) {{ throw_machine_stop!(Zst) }} -pub(crate) struct ConstPropMachine<'mir, 'tcx> { - /// The virtual call stack. - stack: Vec>, +pub(crate) struct ConstPropMachine { pub written_only_inside_own_block_locals: FxHashSet, pub can_const_prop: IndexVec, } -impl ConstPropMachine<'_, '_> { +impl ConstPropMachine { pub fn new(can_const_prop: IndexVec) -> Self { - Self { - stack: Vec::new(), - written_only_inside_own_block_locals: Default::default(), - can_const_prop, - } + Self { written_only_inside_own_block_locals: Default::default(), can_const_prop } } } -impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> { +impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for ConstPropMachine { compile_time_machine!(<'mir, 'tcx>); const PANIC_ON_ALLOC_FAIL: bool = true; // all allocations are small (see `MAX_ALLOC_LIMIT`) @@ -192,16 +186,16 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> #[inline(always)] fn stack<'a>( - ecx: &'a InterpCx<'mir, 'tcx, Self>, + _ecx: &'a InterpCx<'mir, 'tcx, Self>, ) -> &'a [Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>] { - &ecx.machine.stack + &[] } #[inline(always)] fn stack_mut<'a>( - ecx: &'a mut InterpCx<'mir, 'tcx, Self>, + _ecx: &'a mut InterpCx<'mir, 'tcx, Self>, ) -> &'a mut Vec> { - &mut ecx.machine.stack + unreachable!() } } diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index a801d6ec01e7..c1f2447784d9 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -3,8 +3,8 @@ use std::fmt::Debug; -use rustc_const_eval::interpret::{ImmTy, MPlaceTy, Projectable}; -use rustc_const_eval::interpret::{InterpCx, InterpResult, OpTy, Scalar, StackPopCleanup}; +use rustc_const_eval::interpret::{ImmTy, Projectable}; +use rustc_const_eval::interpret::{InterpCx, InterpResult, OpTy, Scalar}; use rustc_hir::def::DefKind; use rustc_hir::HirId; use rustc_index::bit_set::BitSet; @@ -12,10 +12,7 @@ use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; -use rustc_middle::ty::GenericArgs; -use rustc_middle::ty::{ - self, ConstInt, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt, -}; +use rustc_middle::ty::{self, ConstInt, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::Span; use rustc_target::abi::{Abi, FieldIdx, HasDataLayout, Size, TargetDataLayout, VariantIdx}; @@ -72,12 +69,13 @@ impl<'tcx> MirLint<'tcx> for ConstPropLint { /// Finds optimization opportunities on the MIR. struct ConstPropagator<'mir, 'tcx> { - ecx: InterpCx<'mir, 'tcx, ConstPropMachine<'mir, 'tcx>>, + ecx: InterpCx<'mir, 'tcx, ConstPropMachine>, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, worklist: Vec, visited_blocks: BitSet, locals: IndexVec>, + body: &'mir Body<'tcx>, } #[derive(Debug, Clone)] @@ -180,27 +178,16 @@ impl<'tcx> ty::layout::HasParamEnv<'tcx> for ConstPropagator<'_, 'tcx> { impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn new(body: &'mir Body<'tcx>, tcx: TyCtxt<'tcx>) -> ConstPropagator<'mir, 'tcx> { let def_id = body.source.def_id(); - let args = &GenericArgs::identity_for_item(tcx, def_id); let param_env = tcx.param_env_reveal_all_normalized(def_id); let can_const_prop = CanConstProp::check(tcx, param_env, body); - let mut ecx = InterpCx::new( + let ecx = InterpCx::new( tcx, tcx.def_span(def_id), param_env, ConstPropMachine::new(can_const_prop), ); - let ret = MPlaceTy::fake_alloc_zst(ecx.layout_of(tcx.types.unit).unwrap()).into(); - - ecx.push_stack_frame( - Instance::new(def_id, args), - body, - &ret, - StackPopCleanup::Root { cleanup: false }, - ) - .expect("failed to push initial stack frame"); - ConstPropagator { ecx, tcx, @@ -208,15 +195,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { worklist: vec![START_BLOCK], visited_blocks: BitSet::new_empty(body.basic_blocks.len()), locals: IndexVec::from_elem_n(Value::Uninit, body.local_decls.len()), + body, } } - fn body(&self) -> &'mir Body<'tcx> { - self.ecx.frame().body - } - fn local_decls(&self) -> &'mir LocalDecls<'tcx> { - &self.body().local_decls + &self.body.local_decls } fn get_const(&self, place: Place<'tcx>) -> Option<&Value<'tcx>> { @@ -243,7 +227,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } fn lint_root(&self, source_info: SourceInfo) -> Option { - source_info.scope.lint_root(&self.body().source_scopes) + source_info.scope.lint_root(&self.body.source_scopes) } fn use_ecx(&mut self, f: F) -> Option @@ -332,7 +316,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // `AssertKind` only has an `OverflowNeg` variant, so make sure that is // appropriate to use. assert_eq!(op, UnOp::Neg, "Neg is the only UnOp that can overflow"); - let source_info = self.body().source_info(location); + let source_info = self.body.source_info(location); self.report_assert_as_lint( source_info, AssertLint::ArithmeticOverflow( @@ -370,7 +354,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let r_bits = r.to_scalar().to_bits(right_size).ok(); if r_bits.is_some_and(|b| b >= left_size.bits() as u128) { debug!("check_binary_op: reporting assert for {:?}", location); - let source_info = self.body().source_info(location); + let source_info = self.body.source_info(location); let panic = AssertKind::Overflow( op, match l { @@ -398,7 +382,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let (_res, overflow) = this.ecx.overflowing_binary_op(op, &l, &r)?; Ok(overflow) })? { - let source_info = self.body().source_info(location); + let source_info = self.body.source_info(location); self.report_assert_as_lint( source_info, AssertLint::ArithmeticOverflow( @@ -545,7 +529,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Need proper const propagator for these. _ => return None, }; - let source_info = self.body().source_info(location); + let source_info = self.body.source_info(location); self.report_assert_as_lint( source_info, AssertLint::UnconditionalPanic(source_info.span, msg), @@ -579,7 +563,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } use rustc_middle::mir::Rvalue::*; - let layout = self.use_ecx(|this| this.ecx.eval_place(*dest))?.layout; + let layout = self.ecx.layout_of(dest.ty(self.body, self.tcx).ty).ok()?; trace!(?layout); let val: Value<'_> = match *rvalue {