Refactor remove_noop_landing_pads in two loops.

This commit is contained in:
Camille Gillot 2025-09-18 00:36:52 +00:00
parent 99b9a88503
commit cf341eac19

View file

@ -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,7 @@ 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;
}
@ -36,42 +37,44 @@ 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());
// 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()
for &bb in body.basic_blocks.reverse_postorder().iter().rev() {
let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &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;
}
let basic_blocks = body.basic_blocks.as_mut();
for (bb, bbdata) in basic_blocks.iter_enumerated_mut() {
debug!("processing {:?}", bb);
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 {