Skip to content

Commit 8189045

Browse files
committed
Cache CFG layout predecessors during NOP cleanup
1 parent 2e93e40 commit 8189045

1 file changed

Lines changed: 38 additions & 7 deletions

File tree

crates/codegen/src/ir.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2990,8 +2990,15 @@ impl CodeInfo {
29902990
/// Remove NOP instructions from all blocks, but keep NOPs that introduce
29912991
/// a new source line (they serve as line markers for monitoring LINE events).
29922992
fn remove_nops(&mut self) {
2993+
let layout_predecessors = compute_layout_predecessors(&self.blocks);
29932994
let keep_target_start_nops: Vec<_> = (0..self.blocks.len())
2994-
.map(|idx| keep_target_start_no_location_nop(&self.blocks, BlockIdx(idx as u32)))
2995+
.map(|idx| {
2996+
keep_target_start_no_location_nop(
2997+
&self.blocks,
2998+
BlockIdx(idx as u32),
2999+
&layout_predecessors,
3000+
)
3001+
})
29953002
.collect();
29963003
for (block_idx, block) in self.blocks.iter_mut().enumerate() {
29973004
let mut prev_line = None;
@@ -11257,6 +11264,7 @@ fn compute_target_predecessor_flags(blocks: &[Block]) -> TargetPredecessorFlags
1125711264
fn remove_redundant_nops_in_blocks(blocks: &mut [Block]) -> usize {
1125811265
let mut changes = 0;
1125911266
let plain_jump_targets = compute_target_predecessor_flags(blocks).plain_jump;
11267+
let layout_predecessors = compute_layout_predecessors(blocks);
1126011268
let mut block_order = Vec::new();
1126111269
let mut current = BlockIdx(0);
1126211270
while current != BlockIdx::NULL {
@@ -11265,8 +11273,10 @@ fn remove_redundant_nops_in_blocks(blocks: &mut [Block]) -> usize {
1126511273
}
1126611274
for block_idx in block_order {
1126711275
let bi = block_idx.idx();
11268-
let keep_target_start_nop = keep_target_start_no_location_nop(blocks, block_idx);
11269-
let follows_pop_iter_cleanup = layout_predecessor_ends_with_pop_iter(blocks, block_idx);
11276+
let keep_target_start_nop =
11277+
keep_target_start_no_location_nop(blocks, block_idx, &layout_predecessors);
11278+
let follows_pop_iter_cleanup =
11279+
layout_predecessor_ends_with_pop_iter(blocks, block_idx, &layout_predecessors);
1127011280
let mut src_instructions = core::mem::take(&mut blocks[bi].instructions);
1127111281
if !keep_target_start_nop
1127211282
&& matches!(
@@ -11860,7 +11870,11 @@ fn block_starts_with_with_exit_none_call(block: &Block) -> bool {
1186011870
)
1186111871
}
1186211872

11863-
fn keep_target_start_no_location_nop(blocks: &[Block], target: BlockIdx) -> bool {
11873+
fn keep_target_start_no_location_nop(
11874+
blocks: &[Block],
11875+
target: BlockIdx,
11876+
layout_predecessors: &[BlockIdx],
11877+
) -> bool {
1186411878
if target == BlockIdx::NULL {
1186511879
return false;
1186611880
}
@@ -11870,7 +11884,7 @@ fn keep_target_start_no_location_nop(blocks: &[Block], target: BlockIdx) -> bool
1187011884
if !matches!(first.instr.real(), Some(Instruction::Nop)) {
1187111885
return false;
1187211886
}
11873-
let layout_pred = find_layout_predecessor(blocks, target);
11887+
let layout_pred = layout_predecessors[target.idx()];
1187411888
if layout_pred == BlockIdx::NULL {
1187511889
return false;
1187611890
}
@@ -11881,8 +11895,12 @@ fn keep_target_start_no_location_nop(blocks: &[Block], target: BlockIdx) -> bool
1188111895
&& !block_starts_with_with_exit_none_call(&blocks[target.idx()])
1188211896
}
1188311897

11884-
fn layout_predecessor_ends_with_pop_iter(blocks: &[Block], target: BlockIdx) -> bool {
11885-
let layout_pred = find_layout_predecessor(blocks, target);
11898+
fn layout_predecessor_ends_with_pop_iter(
11899+
blocks: &[Block],
11900+
target: BlockIdx,
11901+
layout_predecessors: &[BlockIdx],
11902+
) -> bool {
11903+
let layout_pred = layout_predecessors[target.idx()];
1188611904
layout_pred != BlockIdx::NULL
1188711905
&& block_has_fallthrough(&blocks[layout_pred.idx()])
1188811906
&& next_nonempty_block(blocks, blocks[layout_pred.idx()].next) == target
@@ -13566,6 +13584,19 @@ fn find_layout_predecessor(blocks: &[Block], target: BlockIdx) -> BlockIdx {
1356613584
BlockIdx::NULL
1356713585
}
1356813586

13587+
fn compute_layout_predecessors(blocks: &[Block]) -> Vec<BlockIdx> {
13588+
let mut predecessors = vec![BlockIdx::NULL; blocks.len()];
13589+
let mut current = BlockIdx(0);
13590+
while current != BlockIdx::NULL {
13591+
let next = blocks[current.idx()].next;
13592+
if next != BlockIdx::NULL {
13593+
predecessors[next.idx()] = current;
13594+
}
13595+
current = next;
13596+
}
13597+
predecessors
13598+
}
13599+
1356913600
fn has_unique_fallthrough_origin(
1357013601
blocks: &[Block],
1357113602
reachable: &[bool],

0 commit comments

Comments
 (0)