diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs index b53c1f6d2020..38752bde6b41 100644 --- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs +++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs @@ -1,7 +1,7 @@ use rustc_index::bit_set::DenseBitSet; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -use tracing::debug; +use tracing::{debug, instrument}; use crate::patch::MirPatch; @@ -15,6 +15,7 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads { sess.panic_strategy().unwinds() } + #[instrument(level = "debug", skip(self, _tcx, body))] fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let def_id = body.source.def_id(); debug!(?def_id); @@ -25,7 +26,24 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads { .iter_enumerated() .any(|(_bb, block)| matches!(block.terminator().kind, TerminatorKind::UnwindResume)); if !has_resume { - debug!("remove_noop_landing_pads: no resume block in MIR"); + debug!("no resume block in MIR"); + return; + } + + let mut nop_landing_pads = DenseBitSet::new_empty(body.basic_blocks.len()); + + // This is a post-order traversal, so that if A post-dominates B + // then A will be visited before B. + for (bb, bbdata) in traversal::postorder(body) { + let is_nop_landing_pad = self.is_nop_landing_pad(bbdata, &nop_landing_pads); + debug!("is_nop_landing_pad({bb:?}) = {is_nop_landing_pad}"); + if is_nop_landing_pad { + nop_landing_pads.insert(bb); + } + } + + if nop_landing_pads.is_empty() { + debug!("no nop landing pads in MIR"); return; } @@ -36,42 +54,27 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads { patch.apply(body); resume_block }; - debug!("remove_noop_landing_pads: resume block is {:?}", resume_block); + debug!(?resume_block); - let mut jumps_folded = 0; - let mut landing_pads_removed = 0; - let mut nop_landing_pads = DenseBitSet::new_empty(body.basic_blocks.len()); + let basic_blocks = body.basic_blocks.as_mut(); + for (bb, bbdata) in basic_blocks.iter_enumerated_mut() { + debug!("processing {:?}", bb); - // This is a post-order traversal, so that if A post-dominates B - // then A will be visited before B. - let postorder: Vec<_> = traversal::postorder(body).map(|(bb, _)| bb).collect(); - for bb in postorder { - debug!(" processing {:?}", bb); - if let Some(unwind) = body[bb].terminator_mut().unwind_mut() + if let Some(unwind) = bbdata.terminator_mut().unwind_mut() && let UnwindAction::Cleanup(unwind_bb) = *unwind && nop_landing_pads.contains(unwind_bb) { debug!(" removing noop landing pad"); - landing_pads_removed += 1; *unwind = UnwindAction::Continue; } - body[bb].terminator_mut().successors_mut(|target| { + bbdata.terminator_mut().successors_mut(|target| { if *target != resume_block && nop_landing_pads.contains(*target) { debug!(" folding noop jump to {:?} to resume block", target); *target = resume_block; - jumps_folded += 1; } }); - - let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads); - if is_nop_landing_pad { - nop_landing_pads.insert(bb); - } - debug!(" is_nop_landing_pad({:?}) = {}", bb, is_nop_landing_pad); } - - debug!("removed {:?} jumps and {:?} landing pads", jumps_folded, landing_pads_removed); } fn is_required(&self) -> bool { @@ -82,11 +85,10 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads { impl RemoveNoopLandingPads { fn is_nop_landing_pad( &self, - bb: BasicBlock, - body: &Body<'_>, + bbdata: &BasicBlockData<'_>, nop_landing_pads: &DenseBitSet, ) -> bool { - for stmt in &body[bb].statements { + for stmt in &bbdata.statements { match &stmt.kind { StatementKind::FakeRead(..) | StatementKind::StorageLive(_) @@ -119,7 +121,7 @@ impl RemoveNoopLandingPads { } } - let terminator = body[bb].terminator(); + let terminator = bbdata.terminator(); match terminator.kind { TerminatorKind::Goto { .. } | TerminatorKind::UnwindResume