Auto merge of #147099 - cjgillot:split-nop-landing, r=lcnr
Refactor remove_noop_landing_pads in two loops. The point is to avoid clearing the CFG cache as often. r? `@ghost` for perf
This commit is contained in:
commit
d773bd07d6
1 changed files with 29 additions and 27 deletions
|
|
@ -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<BasicBlock>,
|
||||
) -> 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue