@@ -201,19 +201,28 @@ impl Context {
201
201
}
202
202
203
203
fn remove_rc_instructions ( self , dfg : & mut DataFlowGraph ) {
204
- for ( rc, block) in self . rc_instructions {
205
- let value = match & dfg[ rc] {
206
- Instruction :: IncrementRc { value } => * value,
207
- Instruction :: DecrementRc { value } => * value,
208
- other => {
209
- unreachable ! ( "Expected IncrementRc or DecrementRc instruction, found {other:?}" )
204
+ let unused_rc_values_by_block: HashMap < BasicBlockId , HashSet < InstructionId > > =
205
+ self . rc_instructions . into_iter ( ) . fold ( HashMap :: default ( ) , |mut acc, ( rc, block) | {
206
+ let value = match & dfg[ rc] {
207
+ Instruction :: IncrementRc { value } => * value,
208
+ Instruction :: DecrementRc { value } => * value,
209
+ other => {
210
+ unreachable ! (
211
+ "Expected IncrementRc or DecrementRc instruction, found {other:?}"
212
+ )
213
+ }
214
+ } ;
215
+
216
+ if !self . used_values . contains ( & value) {
217
+ acc. entry ( block) . or_default ( ) . insert ( rc) ;
210
218
}
211
- } ;
219
+ acc
220
+ } ) ;
212
221
213
- // This could be more efficient if we have to remove multiple instructions in a single block
214
- if ! self . used_values . contains ( & value ) {
215
- dfg [ block ] . instructions_mut ( ) . retain ( |instruction| * instruction != rc ) ;
216
- }
222
+ for ( block , instructions_to_remove ) in unused_rc_values_by_block {
223
+ dfg [ block ]
224
+ . instructions_mut ( )
225
+ . retain ( |instruction| !instructions_to_remove . contains ( instruction ) ) ;
217
226
}
218
227
}
219
228
0 commit comments