@@ -153,9 +153,15 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
153
153
}
154
154
155
155
newtype_index ! {
156
+ #[ debug_format = "_v{}" ]
156
157
struct VnIndex { }
157
158
}
158
159
160
+ newtype_index ! {
161
+ #[ debug_format = "_o{}" ]
162
+ struct VnOpaque { }
163
+ }
164
+
159
165
#[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
160
166
enum AddressKind {
161
167
Ref ( BorrowKind ) ,
@@ -167,7 +173,7 @@ enum Value<'tcx> {
167
173
// Root values.
168
174
/// Used to represent values we know nothing about.
169
175
/// The `usize` is a counter incremented by `new_opaque`.
170
- Opaque ( usize ) ,
176
+ Opaque ( VnOpaque ) ,
171
177
/// Evaluated or unevaluated constant value.
172
178
Constant {
173
179
value : Const < ' tcx > ,
@@ -219,8 +225,7 @@ struct ValueSet<'tcx> {
219
225
hashes : IndexVec < VnIndex , u64 > ,
220
226
values : IndexVec < VnIndex , Value < ' tcx > > ,
221
227
types : IndexVec < VnIndex , Ty < ' tcx > > ,
222
- /// Counter to generate different values.
223
- next_opaque : usize ,
228
+ opaques : IndexVec < VnOpaque , VnIndex > ,
224
229
}
225
230
226
231
impl < ' tcx > ValueSet < ' tcx > {
@@ -230,12 +235,16 @@ impl<'tcx> ValueSet<'tcx> {
230
235
hashes : IndexVec :: with_capacity ( num_values) ,
231
236
values : IndexVec :: with_capacity ( num_values) ,
232
237
types : IndexVec :: with_capacity ( num_values) ,
233
- next_opaque : 1 ,
238
+ opaques : IndexVec :: with_capacity ( num_values ) ,
234
239
}
235
240
}
236
241
237
242
#[ allow( rustc:: pass_by_value) ]
238
243
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
+
239
248
let hash: u64 = {
240
249
let mut h = FxHasher :: default ( ) ;
241
250
value. hash ( & mut h) ;
@@ -263,10 +272,14 @@ impl<'tcx> ValueSet<'tcx> {
263
272
}
264
273
265
274
#[ 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
270
283
}
271
284
272
285
#[ inline]
@@ -281,7 +294,7 @@ impl<'tcx> ValueSet<'tcx> {
281
294
282
295
#[ inline]
283
296
fn forget ( & mut self , index : VnIndex ) {
284
- let opaque = self . next_opaque ( ) ;
297
+ let opaque = self . opaques . push ( index ) ;
285
298
self . values [ index] = Value :: Opaque ( opaque) ;
286
299
}
287
300
}
@@ -299,6 +312,8 @@ struct VnState<'body, 'tcx> {
299
312
values : ValueSet < ' tcx > ,
300
313
/// Values evaluated as constants if possible.
301
314
evaluated : IndexVec < VnIndex , Option < OpTy < ' tcx > > > ,
315
+ /// Counter to generate different values.
316
+ next_disambiguator : usize ,
302
317
/// Cache the deref values.
303
318
derefs : Vec < VnIndex > ,
304
319
ssa : & ' body SsaLocals ,
@@ -331,6 +346,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
331
346
rev_locals : IndexVec :: with_capacity ( num_values) ,
332
347
values : ValueSet :: new ( num_values) ,
333
348
evaluated : IndexVec :: with_capacity ( num_values) ,
349
+ next_disambiguator : 1 ,
334
350
derefs : Vec :: new ( ) ,
335
351
ssa,
336
352
dominators,
@@ -360,8 +376,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
360
376
/// from all the others.
361
377
#[ instrument( level = "trace" , skip( self ) , ret) ]
362
378
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
365
392
}
366
393
367
394
/// Create a new `Value::Address` distinct from all the others.
@@ -374,7 +401,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
374
401
}
375
402
AddressKind :: Address ( mutbl) => Ty :: new_ptr ( self . tcx , pty, mutbl. to_mutbl_lossy ( ) ) ,
376
403
} ;
377
- let value = Value :: Address { place, kind, provenance : self . values . next_opaque ( ) } ;
404
+ let value = Value :: Address { place, kind, provenance : self . next_disambiguator ( ) } ;
378
405
self . insert ( ty, value)
379
406
}
380
407
@@ -403,7 +430,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
403
430
} else {
404
431
// Multiple mentions of this constant will yield different values,
405
432
// 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 ( ) ;
407
434
// `disambiguator: 0` means deterministic.
408
435
debug_assert_ne ! ( disambiguator, 0 ) ;
409
436
disambiguator
0 commit comments