@@ -153,9 +153,15 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
153153} 
154154
155155newtype_index !  { 
156+     #[ debug_format = "_v{}" ] 
156157    struct  VnIndex  { } 
157158} 
158159
160+ newtype_index !  { 
161+     #[ debug_format = "_o{}" ] 
162+     struct  VnOpaque  { } 
163+ } 
164+ 
159165#[ derive( Copy ,  Clone ,  Debug ,  PartialEq ,  Eq ,  Hash ) ]  
160166enum  AddressKind  { 
161167    Ref ( BorrowKind ) , 
@@ -167,7 +173,7 @@ enum Value<'tcx> {
167173    // Root values. 
168174    /// Used to represent values we know nothing about. 
169175/// The `usize` is a counter incremented by `new_opaque`. 
170- Opaque ( usize ) , 
176+ Opaque ( VnOpaque ) , 
171177    /// Evaluated or unevaluated constant value. 
172178Constant  { 
173179        value :  Const < ' tcx > , 
@@ -219,8 +225,7 @@ struct ValueSet<'tcx> {
219225    hashes :  IndexVec < VnIndex ,  u64 > , 
220226    values :  IndexVec < VnIndex ,  Value < ' tcx > > , 
221227    types :  IndexVec < VnIndex ,  Ty < ' tcx > > , 
222-     /// Counter to generate different values. 
223- next_opaque :  usize , 
228+     opaques :  IndexVec < VnOpaque ,  VnIndex > , 
224229} 
225230
226231impl < ' tcx >  ValueSet < ' tcx >  { 
@@ -230,12 +235,16 @@ impl<'tcx> ValueSet<'tcx> {
230235            hashes :  IndexVec :: with_capacity ( num_values) , 
231236            values :  IndexVec :: with_capacity ( num_values) , 
232237            types :  IndexVec :: with_capacity ( num_values) , 
233-             next_opaque :   1 , 
238+             opaques :   IndexVec :: with_capacity ( num_values ) , 
234239        } 
235240    } 
236241
237242    #[ allow( rustc:: pass_by_value) ]  
238243    fn  insert ( & mut  self ,  value :  Value < ' tcx > ,  ty :  Ty < ' tcx > )  -> ( VnIndex ,  bool )  { 
244+         if  let  Value :: Opaque ( opaque)  = value { 
245+             return  ( self . opaques [ opaque] ,  false ) ; 
246+         } 
247+ 
239248        let  hash:  u64  = { 
240249            let  mut  h = FxHasher :: default ( ) ; 
241250            value. hash ( & mut  h) ; 
@@ -263,10 +272,14 @@ impl<'tcx> ValueSet<'tcx> {
263272    } 
264273
265274    #[ inline]  
266-     fn  next_opaque ( & mut  self )  -> usize  { 
267-         let  next_opaque = self . next_opaque ; 
268-         self . next_opaque  += 1 ; 
269-         next_opaque
275+     fn  new_opaque ( & mut  self ,  ty :  Ty < ' tcx > )  -> VnIndex  { 
276+         let  index = self . hashes . push ( 0 ) ; 
277+         let  _index = self . types . push ( ty) ; 
278+         debug_assert_eq ! ( index,  _index) ; 
279+         let  opaque = self . opaques . push ( index) ; 
280+         let  _index = self . values . push ( Value :: Opaque ( opaque) ) ; 
281+         debug_assert_eq ! ( index,  _index) ; 
282+         index
270283    } 
271284
272285    #[ inline]  
@@ -281,7 +294,7 @@ impl<'tcx> ValueSet<'tcx> {
281294
282295    #[ inline]  
283296    fn  forget ( & mut  self ,  index :  VnIndex )  { 
284-         let  opaque = self . next_opaque ( ) ; 
297+         let  opaque = self . opaques . push ( index ) ; 
285298        self . values [ index]  = Value :: Opaque ( opaque) ; 
286299    } 
287300} 
@@ -299,6 +312,8 @@ struct VnState<'body, 'tcx> {
299312    values :  ValueSet < ' tcx > , 
300313    /// Values evaluated as constants if possible. 
301314evaluated :  IndexVec < VnIndex ,  Option < OpTy < ' tcx > > > , 
315+     /// Counter to generate different values. 
316+ next_disambiguator :  usize , 
302317    /// Cache the deref values. 
303318derefs :  Vec < VnIndex > , 
304319    ssa :  & ' body  SsaLocals , 
@@ -331,6 +346,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
331346            rev_locals :  IndexVec :: with_capacity ( num_values) , 
332347            values :  ValueSet :: new ( num_values) , 
333348            evaluated :  IndexVec :: with_capacity ( num_values) , 
349+             next_disambiguator :  1 , 
334350            derefs :  Vec :: new ( ) , 
335351            ssa, 
336352            dominators, 
@@ -360,8 +376,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
360376/// from all the others. 
361377#[ instrument( level = "trace" ,  skip( self ) ,  ret) ]  
362378    fn  new_opaque ( & mut  self ,  ty :  Ty < ' tcx > )  -> VnIndex  { 
363-         let  value = Value :: Opaque ( self . values . next_opaque ( ) ) ; 
364-         self . insert ( ty,  value) 
379+         let  index = self . values . new_opaque ( ty) ; 
380+         let  _index = self . evaluated . push ( None ) ; 
381+         debug_assert_eq ! ( index,  _index) ; 
382+         let  _index = self . rev_locals . push ( SmallVec :: new ( ) ) ; 
383+         debug_assert_eq ! ( index,  _index) ; 
384+         index
385+     } 
386+ 
387+     #[ inline]  
388+     fn  next_disambiguator ( & mut  self )  -> usize  { 
389+         let  next_disambiguator = self . next_disambiguator ; 
390+         self . next_disambiguator  += 1 ; 
391+         next_disambiguator
365392    } 
366393
367394    /// Create a new `Value::Address` distinct from all the others. 
@@ -374,7 +401,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
374401            } 
375402            AddressKind :: Address ( mutbl)  => Ty :: new_ptr ( self . tcx ,  pty,  mutbl. to_mutbl_lossy ( ) ) , 
376403        } ; 
377-         let  value = Value :: Address  {  place,  kind,  provenance :  self . values . next_opaque ( )  } ; 
404+         let  value = Value :: Address  {  place,  kind,  provenance :  self . next_disambiguator ( )  } ; 
378405        self . insert ( ty,  value) 
379406    } 
380407
@@ -403,7 +430,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
403430        }  else  { 
404431            // Multiple mentions of this constant will yield different values, 
405432            // so assign a different `disambiguator` to ensure they do not get the same `VnIndex`. 
406-             let  disambiguator = self . values . next_opaque ( ) ; 
433+             let  disambiguator = self . next_disambiguator ( ) ; 
407434            // `disambiguator: 0` means deterministic. 
408435            debug_assert_ne ! ( disambiguator,  0 ) ; 
409436            disambiguator
0 commit comments