@@ -251,15 +251,25 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
251
251
}
252
252
}
253
253
254
- /// Represent the *value* which would be read from `place`.
254
+ /// Represent the *value* which would be read from `place`, and point `place` to a preexisting
255
+ /// place with the same value (if that already exists).
255
256
#[ instrument( level = "trace" , skip( self ) , ret) ]
256
- fn simplify_place ( & mut self , place : & mut Place < ' tcx > , location : Location ) -> Option < VnIndex > {
257
- // Another place that holds the same value.
257
+ fn simplify_place_value (
258
+ & mut self ,
259
+ place : & mut Place < ' tcx > ,
260
+ location : Location ,
261
+ ) -> Option < VnIndex > {
262
+ // Invariant: `place` and `place_ref` point to the same value, even if they point to
263
+ // different memory locations.
258
264
let mut place_ref = place. as_ref ( ) ;
259
- let mut value = self . locals [ place. local ] ?;
260
265
266
+ // Invariant: `value` holds the value up-to the `index`th projection excluded.
267
+ let mut value = self . locals [ place. local ] ?;
261
268
for ( index, proj) in place. projection . iter ( ) . enumerate ( ) {
262
269
if let Some ( local) = self . try_as_local ( value, location) {
270
+ // Both `local` and `Place { local: place.local, projection: projection[..index] }`
271
+ // hold the same value. Therefore, following place holds the value in the original
272
+ // `place`.
263
273
place_ref = PlaceRef { local, projection : & place. projection [ index..] } ;
264
274
}
265
275
@@ -301,14 +311,15 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
301
311
}
302
312
303
313
if let Some ( local) = self . try_as_local ( value, location)
304
- && local != place. local
314
+ && local != place. local // in case we had no projection to begin with.
305
315
{
306
316
* place = local. into ( ) ;
307
317
self . reused_locals . insert ( local) ;
308
318
self . any_replacement = true ;
309
319
} else if place_ref. local != place. local
310
320
|| place_ref. projection . len ( ) < place. projection . len ( )
311
321
{
322
+ // By the invariant on `place_ref`.
312
323
* place = place_ref. project_deeper ( & [ ] , self . tcx ) ;
313
324
self . reused_locals . insert ( place_ref. local ) ;
314
325
self . any_replacement = true ;
@@ -326,7 +337,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
326
337
match * operand {
327
338
Operand :: Constant ( ref constant) => Some ( self . insert ( Value :: Constant ( constant. const_ ) ) ) ,
328
339
Operand :: Copy ( ref mut place) | Operand :: Move ( ref mut place) => {
329
- let value = self . simplify_place ( place, location) ?;
340
+ let value = self . simplify_place_value ( place, location) ?;
330
341
if let Some ( const_) = self . try_as_constant ( value) {
331
342
* operand = Operand :: Constant ( Box :: new ( const_) ) ;
332
343
self . any_replacement = true ;
@@ -379,7 +390,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
379
390
380
391
// Operations.
381
392
Rvalue :: Len ( ref mut place) => {
382
- let place = self . simplify_place ( place, location) ?;
393
+ let place = self . simplify_place_value ( place, location) ?;
383
394
Value :: Len ( place)
384
395
}
385
396
Rvalue :: Cast ( kind, ref mut value, to) => {
@@ -402,7 +413,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
402
413
Value :: UnaryOp ( op, arg)
403
414
}
404
415
Rvalue :: Discriminant ( ref mut place) => {
405
- let place = self . simplify_place ( place, location) ?;
416
+ let place = self . simplify_place_value ( place, location) ?;
406
417
Value :: Discriminant ( place)
407
418
}
408
419
0 commit comments