diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 255dd1eba97f2..0a9f904c491b8 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -623,6 +623,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// /// This is public because it is used by [priroda](https://github.com/oli-obk/priroda) to get an /// OpTy from a local. + #[instrument(skip(self, layout, frame))] pub fn local_to_op( &self, frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>, @@ -630,6 +631,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { let layout = self.layout_of_local(frame, local, layout)?; + trace!(?frame.locals, "here's the locals"); let op = *frame.locals[local].access()?; if matches!(op, Operand::Immediate(_)) { if layout.is_unsized() { @@ -638,6 +640,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_inval!(ConstPropNonsense); } } + trace!(?op, "the op"); Ok(OpTy { op, layout }) } diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 9a16003bdc9ae..c68d8742f1c65 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -360,6 +360,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ConstPropagator { ecx, tcx, param_env, local_decls: &body.local_decls, patch } } + #[instrument(skip(self), level = "debug")] fn get_const(&self, place: Place<'tcx>) -> Option> { let op = match self.ecx.eval_place_to_op(place, None) { Ok(op) => { @@ -381,10 +382,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Try to read the local as an immediate so that if it is representable as a scalar, we can // handle it as such, but otherwise, just return the value as is. - Some(match self.ecx.read_immediate_raw(&op) { + let r = Some(match self.ecx.read_immediate_raw(&op) { Ok(Right(imm)) => imm.into(), _ => op, - }) + }); + + trace!("found = {r:?}"); + + r } /// Remove `local` from the pool of `Locals`. Allows writing to them, @@ -394,6 +399,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ecx.machine.written_only_inside_own_block_locals.remove(&local); } + #[instrument(skip(self), level = "debug")] fn check_rvalue(&mut self, rvalue: &Rvalue<'tcx>) -> Option<()> { // Perform any special handling for specific Rvalue types. // Generally, checks here fall into one of two categories: @@ -509,6 +515,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } } + #[instrument(skip(self), level = "debug")] fn replace_with_const(&mut self, place: Place<'tcx>) -> Option> { // This will return None if the above `const_prop` invocation only "wrote" a // type whose creation requires no write. E.g. a coroutine whose initial state @@ -611,6 +618,7 @@ impl CanConstProp { } impl<'tcx> Visitor<'tcx> for CanConstProp { + #[instrument(skip(self), level = "debug")] fn visit_place(&mut self, place: &Place<'tcx>, mut context: PlaceContext, loc: Location) { use rustc_middle::mir::visit::PlaceContext::*; @@ -623,6 +631,7 @@ impl<'tcx> Visitor<'tcx> for CanConstProp { self.visit_projection(place.as_ref(), context, loc); } + #[instrument(skip(self), level = "debug")] fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) { use rustc_middle::mir::visit::PlaceContext::*; match context { @@ -681,15 +690,22 @@ impl<'tcx> Visitor<'tcx> for CanConstProp { } impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { + #[instrument(skip(self), level = "debug")] fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { self.super_operand(operand, location); + + trace!("about to do it"); + if let Some(place) = operand.place() && let Some(value) = self.replace_with_const(place) { + trace!(?place, ?value, "know whats going on"); self.patch.before_effect.insert((location, place), value); } } + #[instrument(skip(self), level = "debug")] + fn visit_projection_elem( &mut self, _: PlaceRef<'tcx>, @@ -704,6 +720,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { } } + #[instrument(skip(self), level = "debug")] fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { self.super_assign(place, rvalue, location); @@ -714,14 +731,14 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { _ if place.is_indirect() => {} ConstPropMode::NoPropagation => self.ensure_not_propagated(place.local), ConstPropMode::OnlyInsideOwnBlock | ConstPropMode::FullConstProp => { + trace!("trying to do some const-prop"); if let Some(()) = self.eval_rvalue_with_identities(rvalue, *place) { // If this was already an evaluated constant, keep it. if let Rvalue::Use(Operand::Constant(c)) = rvalue && let Const::Val(..) = c.const_ { trace!( - "skipping replace of Rvalue::Use({:?} because it is already a const", - c + "skipping replace of Rvalue::Use({c:?}) because it is already a const" ); } else if let Some(operand) = self.replace_with_const(*place) { self.patch.assignments.insert(location, operand); @@ -748,8 +765,12 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { } } + #[instrument(skip(self), level = "trace")] fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { - trace!("visit_statement: {:?}", statement); + { + let frame = &self.ecx.frame().locals; + trace!(?frame, "initial frame"); + } // We want to evaluate operands before any change to the assigned-to value, // so we recurse first. @@ -790,6 +811,11 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { // In both cases, this does not matter, as those reads would be UB anyway. _ => {} } + + { + let frame = &self.ecx.frame().locals; + trace!(?frame, "final frame"); + } } fn visit_basic_block_data(&mut self, block: BasicBlock, data: &BasicBlockData<'tcx>) {