@@ -157,13 +157,25 @@ impl<A: BumpAllocator> Canonicalization<A> {
157157 & mut self ,
158158 context : & mut MirContext < ' _ , ' heap > ,
159159 bodies : & mut DefIdSlice < Body < ' heap > > ,
160-
160+ unstable : & mut DenseBitSet < DefId > ,
161161 state : & mut DefIdSlice < Changed > ,
162162 ) -> Changed {
163- self . alloc . scoped ( |alloc| {
163+ let changed : Changed = self . alloc . scoped ( |alloc| {
164164 let pass = AdministrativeReduction :: new_in ( alloc) ;
165165 Self :: run_global_pass ( context, bodies, pass, state)
166- } )
166+ } ) ;
167+
168+ if changed != Changed :: No {
169+ // If we've changed, re-queue any that have changed. This allows us to propagate changes
170+ // earlier and potentially skip redundant iterations.
171+ for ( id, & changed) in state. iter_enumerated ( ) {
172+ if changed != Changed :: No {
173+ unstable. insert ( id) ;
174+ }
175+ }
176+ }
177+
178+ changed
167179 }
168180
169181 fn dse < ' heap > (
@@ -237,7 +249,7 @@ impl<'env, 'heap, A: BumpAllocator> GlobalTransformPass<'env, 'heap> for Canonic
237249 // producing a minimal CFG that maximizes the next iteration's effectiveness.
238250
239251 let mut changed = Changed :: No ;
240- changed |= self . administrative_reduction ( context, bodies, state) ;
252+ changed |= self . administrative_reduction ( context, bodies, & mut unstable , state) ;
241253 changed |= self . inst_simplify ( context, bodies, & unstable, state) ;
242254
243255 // FS vs CP strategy: ForwardSubstitution is more powerful but expensive;
@@ -277,6 +289,7 @@ impl<'env, 'heap, A: BumpAllocator> GlobalTransformPass<'env, 'heap> for Canonic
277289 iter += 1 ;
278290 }
279291
292+ global. overlay ( state) ;
280293 global_changed
281294 }
282295}
0 commit comments