@@ -101,14 +101,15 @@ impl SsaLocals {
101
101
. retain ( |& local| matches ! ( visitor. assignments[ local] , Set1 :: One ( _) ) ) ;
102
102
debug ! ( ?visitor. assignment_order) ;
103
103
104
- let copy_classes = compute_copy_classes ( & mut visitor, body) ;
105
-
106
- SsaLocals {
104
+ let mut ssa = SsaLocals {
107
105
assignments : visitor. assignments ,
108
106
assignment_order : visitor. assignment_order ,
109
107
direct_uses : visitor. direct_uses ,
110
- copy_classes,
111
- }
108
+ // This is filled by `compute_copy_classes`.
109
+ copy_classes : IndexVec :: default ( ) ,
110
+ } ;
111
+ compute_copy_classes ( & mut ssa, body) ;
112
+ ssa
112
113
}
113
114
114
115
pub fn num_locals ( & self ) -> usize {
@@ -261,27 +262,19 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor {
261
262
}
262
263
263
264
#[ instrument( level = "trace" , skip( ssa, body) ) ]
264
- fn compute_copy_classes ( ssa : & mut SsaVisitor , body : & Body < ' _ > ) -> IndexVec < Local , Local > {
265
+ fn compute_copy_classes ( ssa : & mut SsaLocals , body : & Body < ' _ > ) {
266
+ let mut direct_uses = std:: mem:: take ( & mut ssa. direct_uses ) ;
265
267
let mut copies = IndexVec :: from_fn_n ( |l| l, body. local_decls . len ( ) ) ;
266
268
267
- for & local in & ssa. assignment_order {
268
- debug ! ( ?local) ;
269
-
270
- // This is not SSA: mark that we don't know the value.
271
- debug ! ( assignments = ?ssa. assignments[ local] ) ;
272
- let Set1 :: One ( LocationExtended :: Plain ( loc) ) = ssa. assignments [ local] else { continue } ;
273
-
274
- // `loc` must point to a direct assignment to `local`.
275
- let Either :: Left ( stmt) = body. stmt_at ( loc) else { bug ! ( ) } ;
276
- let Some ( ( _target, rvalue) ) = stmt. kind . as_assign ( ) else { bug ! ( ) } ;
277
- assert_eq ! ( _target. as_local( ) , Some ( local) ) ;
278
-
269
+ for ( local, rvalue, _) in ssa. assignments ( body) {
279
270
let ( Rvalue :: Use ( Operand :: Copy ( place) | Operand :: Move ( place) ) | Rvalue :: CopyForDeref ( place) )
280
271
= rvalue
281
272
else { continue } ;
282
273
283
274
let Some ( rhs) = place. as_local ( ) else { continue } ;
284
- let Set1 :: One ( _) = ssa. assignments [ rhs] else { continue } ;
275
+ if !ssa. is_ssa ( rhs) {
276
+ continue ;
277
+ }
285
278
286
279
// We visit in `assignment_order`, ie. reverse post-order, so `rhs` has been
287
280
// visited before `local`, and we just have to copy the representing local.
@@ -302,11 +295,11 @@ fn compute_copy_classes(ssa: &mut SsaVisitor, body: &Body<'_>) -> IndexVec<Local
302
295
} else {
303
296
copies[ local] = head;
304
297
}
305
- ssa . direct_uses [ rhs] -= 1 ;
298
+ direct_uses[ rhs] -= 1 ;
306
299
}
307
300
308
301
debug ! ( ?copies) ;
309
- debug ! ( ?ssa . direct_uses) ;
302
+ debug ! ( ?direct_uses) ;
310
303
311
304
// Invariant: `copies` must point to the head of an equivalence class.
312
305
#[ cfg( debug_assertions) ]
@@ -315,7 +308,8 @@ fn compute_copy_classes(ssa: &mut SsaVisitor, body: &Body<'_>) -> IndexVec<Local
315
308
}
316
309
debug_assert_eq ! ( copies[ RETURN_PLACE ] , RETURN_PLACE ) ;
317
310
318
- copies
311
+ ssa. direct_uses = direct_uses;
312
+ ssa. copy_classes = copies;
319
313
}
320
314
321
315
#[ derive( Debug ) ]
0 commit comments