@@ -94,7 +94,7 @@ use rustc_const_eval::interpret::{
9494    ImmTy ,  Immediate ,  InterpCx ,  MemPlaceMeta ,  MemoryKind ,  OpTy ,  Projectable ,  Scalar , 
9595    intern_const_alloc_for_constprop, 
9696} ; 
97- use  rustc_data_structures:: fx:: { FxIndexSet ,  MutableValues } ; 
97+ use  rustc_data_structures:: fx:: { FxHashMap ,   FxIndexSet ,  MutableValues } ; 
9898use  rustc_data_structures:: graph:: dominators:: Dominators ; 
9999use  rustc_hir:: def:: DefKind ; 
100100use  rustc_index:: bit_set:: DenseBitSet ; 
@@ -229,8 +229,10 @@ struct VnState<'body, 'a, 'tcx> {
229229    /// Value stored in each local. 
230230locals :  IndexVec < Local ,  VnIndex > , 
231231    /// Locals that are assigned that value. 
232- // This vector does not hold all the values of `VnIndex` that we create. 
233-     rev_locals :  IndexVec < VnIndex ,  SmallVec < [ ( Local ,  Location ) ;  1 ] > > , 
232+ // This vector holds the locals that are SSA. 
233+     rev_locals_ssa :  IndexVec < VnIndex ,  SmallVec < [ ( Local ,  Location ) ;  1 ] > > , 
234+     // This vector holds the locals that are not SSA. 
235+     rev_locals_non_ssa :  FxHashMap < VnIndex ,  SmallVec < [ ( Local ,  Location ) ;  1 ] > > , 
234236    values :  FxIndexSet < ( Value < ' a ,  ' tcx > ,  Ty < ' tcx > ) > , 
235237    /// Values evaluated as constants if possible. 
236238evaluated :  IndexVec < VnIndex ,  Option < OpTy < ' tcx > > > , 
@@ -267,7 +269,8 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
267269            local_decls, 
268270            is_coroutine :  body. coroutine . is_some ( ) , 
269271            locals :  IndexVec :: with_capacity ( body. local_decls . len ( ) ) , 
270-             rev_locals :  IndexVec :: with_capacity ( num_values) , 
272+             rev_locals_ssa :  IndexVec :: with_capacity ( num_values) , 
273+             rev_locals_non_ssa :  FxHashMap :: default ( ) , 
271274            values :  FxIndexSet :: with_capacity_and_hasher ( num_values,  Default :: default ( ) ) , 
272275            evaluated :  IndexVec :: with_capacity ( num_values) , 
273276            next_opaque :  1 , 
@@ -281,7 +284,11 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
281284        for  decl in  body. local_decls . iter ( )  { 
282285            let  value = this. new_opaque ( decl. ty ) ; 
283286            let  local = this. locals . push ( value) ; 
284-             this. rev_locals [ value] . push ( ( local,  init_loc) ) ; 
287+             if  ssa. is_ssa ( local)  { 
288+                 this. rev_locals_ssa [ value] . push ( ( local,  init_loc) ) ; 
289+             }  else  { 
290+                 this. rev_locals_non_ssa . entry ( value) . or_default ( ) . push ( ( local,  init_loc) ) ; 
291+             } 
285292        } 
286293        this
287294    } 
@@ -299,7 +306,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
299306            let  evaluated = self . eval_to_const ( index) ; 
300307            let  _index = self . evaluated . push ( evaluated) ; 
301308            debug_assert_eq ! ( index,  _index) ; 
302-             let  _index = self . rev_locals . push ( SmallVec :: new ( ) ) ; 
309+             let  _index = self . rev_locals_ssa . push ( Default :: default ( ) ) ; 
303310            debug_assert_eq ! ( index,  _index) ; 
304311        } 
305312        index
@@ -370,7 +377,11 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
370377#[ instrument( level = "trace" ,  skip( self ) ) ]  
371378    fn  assign ( & mut  self ,  local :  Local ,  value :  VnIndex ,  loc :  Location )  { 
372379        self . locals [ local]  = value; 
373-         self . rev_locals [ value] . push ( ( local,  loc) ) ; 
380+         if  self . ssa . is_ssa ( local)  { 
381+             self . rev_locals_ssa [ value] . push ( ( local,  loc) ) ; 
382+         }  else  { 
383+             self . rev_locals_non_ssa . entry ( value) . or_default ( ) . push ( ( local,  loc) ) ; 
384+         } 
374385    } 
375386
376387    #[ instrument( level = "trace" ,  skip( self ) ) ]  
@@ -380,11 +391,11 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
380391                return ; 
381392            } 
382393            let  value = this. locals [ local] ; 
383-             this. rev_locals [ value] . retain ( |( l,  _) | * l != local) ; 
394+             this. rev_locals_non_ssa . entry ( value) . or_default ( ) . retain ( |( l,  _) | * l != local) ; 
384395            this. locals [ local]  = this. new_opaque ( this. ty ( value) ) ; 
385396            #[ cfg( debug_assertions) ]  
386-             for  local_vec in  this. rev_locals . iter ( )  { 
387-                 for  ( other,  _)  in  local_vec { 
397+             for  local_vec in  this. rev_locals_non_ssa . iter ( )  { 
398+                 for  ( other,  _)  in  local_vec. non_ssa  { 
388399                    debug_assert_ne ! ( * other,  local) ; 
389400                } 
390401            } 
@@ -1769,9 +1780,10 @@ impl<'tcx> VnState<'_, '_, 'tcx> {
17691780/// return it. If you used this local, add it to `reused_locals` to remove storage statements. 
17701781#[ instrument( level = "trace" ,  skip( self ) ,  ret) ]  
17711782    fn  try_as_local ( & mut  self ,  index :  VnIndex ,  loc :  Location )  -> Option < Local >  { 
1772-         let  other = self . rev_locals . get ( index) ?; 
1773-         other
1774-             . iter ( ) 
1783+         let  ssa = self . rev_locals_ssa . get ( index) ?; 
1784+         let  non_ssa = self . rev_locals_non_ssa . entry ( index) . or_default ( ) ; 
1785+         ssa. iter ( ) 
1786+             . chain ( non_ssa. iter ( ) ) 
17751787            . find ( |& & ( other,  assign_loc) | { 
17761788                self . ssa . assignment_dominates ( & self . dominators ,  other,  loc) 
17771789                    || ( assign_loc. block  == loc. block 
@@ -1787,15 +1799,16 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, '_, 'tcx> {
17871799    } 
17881800
17891801    fn  visit_basic_block_data ( & mut  self ,  block :  BasicBlock ,  bbdata :  & mut  BasicBlockData < ' tcx > )  { 
1790-         for  local_set in  self . rev_locals . iter_mut ( )  { 
1791-             local_set. retain ( |( local,  _) | self . ssa . is_ssa ( * local) ) ; 
1792-         } 
1802+         self . rev_locals_non_ssa . clear ( ) ; 
17931803        for  local in  self . locals . indices ( )  { 
17941804            if  !self . ssa . is_ssa ( local)  { 
17951805                let  current = self . locals [ local] ; 
17961806                let  new = self . new_opaque ( self . ty ( current) ) ; 
17971807                self . locals [ local]  = new; 
1798-                 self . rev_locals [ new] . push ( ( local,  Location  {  block,  statement_index :  0  } ) ) ; 
1808+                 self . rev_locals_non_ssa 
1809+                     . entry ( new) 
1810+                     . or_default ( ) 
1811+                     . push ( ( local,  Location  {  block,  statement_index :  0  } ) ) ; 
17991812            } 
18001813        } 
18011814        self . super_basic_block_data ( block,  bbdata) ; 
0 commit comments