Skip to content

Commit d773bd0

Browse files
committed
Auto merge of rust-lang#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
2 parents ff5be13 + 94b2c30 commit d773bd0

File tree

1 file changed

+29
-27
lines changed

1 file changed

+29
-27
lines changed

compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc_index::bit_set::DenseBitSet;
22
use rustc_middle::mir::*;
33
use rustc_middle::ty::TyCtxt;
4-
use tracing::debug;
4+
use tracing::{debug, instrument};
55

66
use crate::patch::MirPatch;
77

@@ -15,6 +15,7 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
1515
sess.panic_strategy().unwinds()
1616
}
1717

18+
#[instrument(level = "debug", skip(self, _tcx, body))]
1819
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
1920
let def_id = body.source.def_id();
2021
debug!(?def_id);
@@ -25,7 +26,24 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
2526
.iter_enumerated()
2627
.any(|(_bb, block)| matches!(block.terminator().kind, TerminatorKind::UnwindResume));
2728
if !has_resume {
28-
debug!("remove_noop_landing_pads: no resume block in MIR");
29+
debug!("no resume block in MIR");
30+
return;
31+
}
32+
33+
let mut nop_landing_pads = DenseBitSet::new_empty(body.basic_blocks.len());
34+
35+
// This is a post-order traversal, so that if A post-dominates B
36+
// then A will be visited before B.
37+
for (bb, bbdata) in traversal::postorder(body) {
38+
let is_nop_landing_pad = self.is_nop_landing_pad(bbdata, &nop_landing_pads);
39+
debug!("is_nop_landing_pad({bb:?}) = {is_nop_landing_pad}");
40+
if is_nop_landing_pad {
41+
nop_landing_pads.insert(bb);
42+
}
43+
}
44+
45+
if nop_landing_pads.is_empty() {
46+
debug!("no nop landing pads in MIR");
2947
return;
3048
}
3149

@@ -36,42 +54,27 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
3654
patch.apply(body);
3755
resume_block
3856
};
39-
debug!("remove_noop_landing_pads: resume block is {:?}", resume_block);
57+
debug!(?resume_block);
4058

41-
let mut jumps_folded = 0;
42-
let mut landing_pads_removed = 0;
43-
let mut nop_landing_pads = DenseBitSet::new_empty(body.basic_blocks.len());
59+
let basic_blocks = body.basic_blocks.as_mut();
60+
for (bb, bbdata) in basic_blocks.iter_enumerated_mut() {
61+
debug!("processing {:?}", bb);
4462

45-
// This is a post-order traversal, so that if A post-dominates B
46-
// then A will be visited before B.
47-
let postorder: Vec<_> = traversal::postorder(body).map(|(bb, _)| bb).collect();
48-
for bb in postorder {
49-
debug!(" processing {:?}", bb);
50-
if let Some(unwind) = body[bb].terminator_mut().unwind_mut()
63+
if let Some(unwind) = bbdata.terminator_mut().unwind_mut()
5164
&& let UnwindAction::Cleanup(unwind_bb) = *unwind
5265
&& nop_landing_pads.contains(unwind_bb)
5366
{
5467
debug!(" removing noop landing pad");
55-
landing_pads_removed += 1;
5668
*unwind = UnwindAction::Continue;
5769
}
5870

59-
body[bb].terminator_mut().successors_mut(|target| {
71+
bbdata.terminator_mut().successors_mut(|target| {
6072
if *target != resume_block && nop_landing_pads.contains(*target) {
6173
debug!(" folding noop jump to {:?} to resume block", target);
6274
*target = resume_block;
63-
jumps_folded += 1;
6475
}
6576
});
66-
67-
let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads);
68-
if is_nop_landing_pad {
69-
nop_landing_pads.insert(bb);
70-
}
71-
debug!(" is_nop_landing_pad({:?}) = {}", bb, is_nop_landing_pad);
7277
}
73-
74-
debug!("removed {:?} jumps and {:?} landing pads", jumps_folded, landing_pads_removed);
7578
}
7679

7780
fn is_required(&self) -> bool {
@@ -82,11 +85,10 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
8285
impl RemoveNoopLandingPads {
8386
fn is_nop_landing_pad(
8487
&self,
85-
bb: BasicBlock,
86-
body: &Body<'_>,
88+
bbdata: &BasicBlockData<'_>,
8789
nop_landing_pads: &DenseBitSet<BasicBlock>,
8890
) -> bool {
89-
for stmt in &body[bb].statements {
91+
for stmt in &bbdata.statements {
9092
match &stmt.kind {
9193
StatementKind::FakeRead(..)
9294
| StatementKind::StorageLive(_)
@@ -119,7 +121,7 @@ impl RemoveNoopLandingPads {
119121
}
120122
}
121123

122-
let terminator = body[bb].terminator();
124+
let terminator = bbdata.terminator();
123125
match terminator.kind {
124126
TerminatorKind::Goto { .. }
125127
| TerminatorKind::UnwindResume

0 commit comments

Comments
 (0)