Skip to content

Commit 901be42

Browse files
committed
Explicit simplify_place.
1 parent b2ff77c commit 901be42

File tree

1 file changed

+19
-8
lines changed
  • compiler/rustc_mir_transform/src

1 file changed

+19
-8
lines changed

compiler/rustc_mir_transform/src/gvn.rs

+19-8
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,25 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
251251
}
252252
}
253253

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).
255256
#[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.
258264
let mut place_ref = place.as_ref();
259-
let mut value = self.locals[place.local]?;
260265

266+
// Invariant: `value` holds the value up-to the `index`th projection excluded.
267+
let mut value = self.locals[place.local]?;
261268
for (index, proj) in place.projection.iter().enumerate() {
262269
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`.
263273
place_ref = PlaceRef { local, projection: &place.projection[index..] };
264274
}
265275

@@ -301,14 +311,15 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
301311
}
302312

303313
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.
305315
{
306316
*place = local.into();
307317
self.reused_locals.insert(local);
308318
self.any_replacement = true;
309319
} else if place_ref.local != place.local
310320
|| place_ref.projection.len() < place.projection.len()
311321
{
322+
// By the invariant on `place_ref`.
312323
*place = place_ref.project_deeper(&[], self.tcx);
313324
self.reused_locals.insert(place_ref.local);
314325
self.any_replacement = true;
@@ -326,7 +337,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
326337
match *operand {
327338
Operand::Constant(ref constant) => Some(self.insert(Value::Constant(constant.const_))),
328339
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)?;
330341
if let Some(const_) = self.try_as_constant(value) {
331342
*operand = Operand::Constant(Box::new(const_));
332343
self.any_replacement = true;
@@ -379,7 +390,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
379390

380391
// Operations.
381392
Rvalue::Len(ref mut place) => {
382-
let place = self.simplify_place(place, location)?;
393+
let place = self.simplify_place_value(place, location)?;
383394
Value::Len(place)
384395
}
385396
Rvalue::Cast(kind, ref mut value, to) => {
@@ -402,7 +413,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
402413
Value::UnaryOp(op, arg)
403414
}
404415
Rvalue::Discriminant(ref mut place) => {
405-
let place = self.simplify_place(place, location)?;
416+
let place = self.simplify_place_value(place, location)?;
406417
Value::Discriminant(place)
407418
}
408419

0 commit comments

Comments
 (0)