diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/die.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/die.rs index 8d3fa9cc615..dbdb6e3b4ef 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/die.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/die.rs @@ -201,19 +201,28 @@ impl Context { } fn remove_rc_instructions(self, dfg: &mut DataFlowGraph) { - for (rc, block) in self.rc_instructions { - let value = match &dfg[rc] { - Instruction::IncrementRc { value } => *value, - Instruction::DecrementRc { value } => *value, - other => { - unreachable!("Expected IncrementRc or DecrementRc instruction, found {other:?}") + let unused_rc_values_by_block: HashMap> = + self.rc_instructions.into_iter().fold(HashMap::default(), |mut acc, (rc, block)| { + let value = match &dfg[rc] { + Instruction::IncrementRc { value } => *value, + Instruction::DecrementRc { value } => *value, + other => { + unreachable!( + "Expected IncrementRc or DecrementRc instruction, found {other:?}" + ) + } + }; + + if !self.used_values.contains(&value) { + acc.entry(block).or_default().insert(rc); } - }; + acc + }); - // This could be more efficient if we have to remove multiple instructions in a single block - if !self.used_values.contains(&value) { - dfg[block].instructions_mut().retain(|instruction| *instruction != rc); - } + for (block, instructions_to_remove) in unused_rc_values_by_block { + dfg[block] + .instructions_mut() + .retain(|instruction| !instructions_to_remove.contains(instruction)); } }