Invalidate all dereferences for non-local assignments
This commit is contained in:
parent
84af556791
commit
7830406df1
3 changed files with 35 additions and 13 deletions
|
@ -9,6 +9,8 @@ pub type FxIndexSet<V> = indexmap::IndexSet<V, BuildHasherDefault<FxHasher>>;
|
||||||
pub type IndexEntry<'a, K, V> = indexmap::map::Entry<'a, K, V>;
|
pub type IndexEntry<'a, K, V> = indexmap::map::Entry<'a, K, V>;
|
||||||
pub type IndexOccupiedEntry<'a, K, V> = indexmap::map::OccupiedEntry<'a, K, V>;
|
pub type IndexOccupiedEntry<'a, K, V> = indexmap::map::OccupiedEntry<'a, K, V>;
|
||||||
|
|
||||||
|
pub use indexmap::set::MutableValues;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! define_id_collections {
|
macro_rules! define_id_collections {
|
||||||
($map_name:ident, $set_name:ident, $entry_name:ident, $key:ty) => {
|
($map_name:ident, $set_name:ident, $entry_name:ident, $key:ty) => {
|
||||||
|
|
|
@ -93,7 +93,7 @@ use rustc_const_eval::interpret::{
|
||||||
ImmTy, Immediate, InterpCx, MemPlaceMeta, MemoryKind, OpTy, Projectable, Scalar,
|
ImmTy, Immediate, InterpCx, MemPlaceMeta, MemoryKind, OpTy, Projectable, Scalar,
|
||||||
intern_const_alloc_for_constprop,
|
intern_const_alloc_for_constprop,
|
||||||
};
|
};
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::{FxIndexSet, MutableValues};
|
||||||
use rustc_data_structures::graph::dominators::Dominators;
|
use rustc_data_structures::graph::dominators::Dominators;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_index::bit_set::DenseBitSet;
|
use rustc_index::bit_set::DenseBitSet;
|
||||||
|
@ -238,6 +238,8 @@ struct VnState<'body, 'tcx> {
|
||||||
evaluated: IndexVec<VnIndex, Option<OpTy<'tcx>>>,
|
evaluated: IndexVec<VnIndex, Option<OpTy<'tcx>>>,
|
||||||
/// Counter to generate different values.
|
/// Counter to generate different values.
|
||||||
next_opaque: usize,
|
next_opaque: usize,
|
||||||
|
/// Cache the deref values.
|
||||||
|
derefs: Vec<VnIndex>,
|
||||||
/// Cache the value of the `unsized_locals` features, to avoid fetching it repeatedly in a loop.
|
/// Cache the value of the `unsized_locals` features, to avoid fetching it repeatedly in a loop.
|
||||||
feature_unsized_locals: bool,
|
feature_unsized_locals: bool,
|
||||||
ssa: &'body SsaLocals,
|
ssa: &'body SsaLocals,
|
||||||
|
@ -270,6 +272,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
values: FxIndexSet::with_capacity_and_hasher(num_values, Default::default()),
|
values: FxIndexSet::with_capacity_and_hasher(num_values, Default::default()),
|
||||||
evaluated: IndexVec::with_capacity(num_values),
|
evaluated: IndexVec::with_capacity(num_values),
|
||||||
next_opaque: 1,
|
next_opaque: 1,
|
||||||
|
derefs: Vec::new(),
|
||||||
feature_unsized_locals: tcx.features().unsized_locals(),
|
feature_unsized_locals: tcx.features().unsized_locals(),
|
||||||
ssa,
|
ssa,
|
||||||
dominators,
|
dominators,
|
||||||
|
@ -368,6 +371,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
self.insert(Value::Aggregate(AggregateTy::Tuple, VariantIdx::ZERO, values))
|
self.insert(Value::Aggregate(AggregateTy::Tuple, VariantIdx::ZERO, values))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn insert_deref(&mut self, value: VnIndex) -> VnIndex {
|
||||||
|
let value = self.insert(Value::Projection(value, ProjectionElem::Deref));
|
||||||
|
self.derefs.push(value);
|
||||||
|
value
|
||||||
|
}
|
||||||
|
|
||||||
|
fn invalidate_derefs(&mut self) {
|
||||||
|
for deref in std::mem::take(&mut self.derefs) {
|
||||||
|
let opaque = self.next_opaque();
|
||||||
|
*self.values.get_index_mut2(deref.index()).unwrap() = Value::Opaque(opaque);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self), ret)]
|
#[instrument(level = "trace", skip(self), ret)]
|
||||||
fn eval_to_const(&mut self, value: VnIndex) -> Option<OpTy<'tcx>> {
|
fn eval_to_const(&mut self, value: VnIndex) -> Option<OpTy<'tcx>> {
|
||||||
use Value::*;
|
use Value::*;
|
||||||
|
@ -634,7 +650,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
{
|
{
|
||||||
// An immutable borrow `_x` always points to the same value for the
|
// An immutable borrow `_x` always points to the same value for the
|
||||||
// lifetime of the borrow, so we can merge all instances of `*_x`.
|
// lifetime of the borrow, so we can merge all instances of `*_x`.
|
||||||
ProjectionElem::Deref
|
return Some(self.insert_deref(value));
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -1739,6 +1755,8 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
|
||||||
self.assign(local, value);
|
self.assign(local, value);
|
||||||
Some(value)
|
Some(value)
|
||||||
} else {
|
} else {
|
||||||
|
// Non-local assignments maybe invalidate deref.
|
||||||
|
self.invalidate_derefs();
|
||||||
value
|
value
|
||||||
};
|
};
|
||||||
let Some(value) = value else { return };
|
let Some(value) = value else { return };
|
||||||
|
@ -1758,12 +1776,16 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) {
|
fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) {
|
||||||
if let Terminator { kind: TerminatorKind::Call { destination, .. }, .. } = terminator
|
if let Terminator { kind: TerminatorKind::Call { destination, .. }, .. } = terminator {
|
||||||
&& let Some(local) = destination.as_local()
|
if let Some(local) = destination.as_local()
|
||||||
&& self.ssa.is_ssa(local)
|
&& self.ssa.is_ssa(local)
|
||||||
{
|
{
|
||||||
let opaque = self.new_opaque();
|
let opaque = self.new_opaque();
|
||||||
self.assign(local, opaque);
|
self.assign(local, opaque);
|
||||||
|
}
|
||||||
|
// Function calls maybe invalidate nested deref, and non-local assignments maybe invalidate deref.
|
||||||
|
// Currently, no distinction is made between these two cases.
|
||||||
|
self.invalidate_derefs();
|
||||||
}
|
}
|
||||||
self.super_terminator(terminator, location);
|
self.super_terminator(terminator, location);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
bb0: {
|
bb0: {
|
||||||
- StorageLive(_2);
|
StorageLive(_2);
|
||||||
+ nop;
|
|
||||||
StorageLive(_3);
|
StorageLive(_3);
|
||||||
StorageLive(_4);
|
StorageLive(_4);
|
||||||
_4 = &_1;
|
_4 = &_1;
|
||||||
|
@ -50,13 +49,12 @@
|
||||||
StorageLive(_9);
|
StorageLive(_9);
|
||||||
_9 = copy _6;
|
_9 = copy _6;
|
||||||
- _0 = Option::<i32>::Some(move _9);
|
- _0 = Option::<i32>::Some(move _9);
|
||||||
+ _0 = copy (*_2);
|
+ _0 = Option::<i32>::Some(copy _6);
|
||||||
StorageDead(_9);
|
StorageDead(_9);
|
||||||
- StorageDead(_6);
|
- StorageDead(_6);
|
||||||
+ nop;
|
+ nop;
|
||||||
StorageDead(_4);
|
StorageDead(_4);
|
||||||
- StorageDead(_2);
|
StorageDead(_2);
|
||||||
+ nop;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue