@@ -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
1125711264fn 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+
1356913600fn has_unique_fallthrough_origin(
1357013601 blocks: &[Block],
1357113602 reachable: &[bool],
0 commit comments