@@ -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.
172178 Constant {
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.
301314 evaluated : IndexVec < VnIndex , Option < OpTy < ' tcx > > > ,
315+ /// Counter to generate different values.
316+ next_disambiguator : usize ,
302317 /// Cache the deref values.
303318 derefs : 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