Improve value_analysis API.

This commit is contained in:
Camille GILLOT 2023-01-29 14:20:45 +00:00
parent c48756cdbf
commit 9af191f86f

View file

@ -735,20 +735,31 @@ impl Map {
} }
/// Locates the given place, if it exists in the tree. /// Locates the given place, if it exists in the tree.
pub fn find(&self, place: PlaceRef<'_>) -> Option<PlaceIndex> { pub fn find_extra(
&self,
place: PlaceRef<'_>,
extra: impl IntoIterator<Item = TrackElem>,
) -> Option<PlaceIndex> {
let mut index = *self.locals.get(place.local)?.as_ref()?; let mut index = *self.locals.get(place.local)?.as_ref()?;
for &elem in place.projection { for &elem in place.projection {
index = self.apply(index, elem.try_into().ok()?)?; index = self.apply(index, elem.try_into().ok()?)?;
} }
for elem in extra {
index = self.apply(index, elem)?;
}
Some(index) Some(index)
} }
/// Locates the given place, if it exists in the tree. /// Locates the given place, if it exists in the tree.
pub fn find(&self, place: PlaceRef<'_>) -> Option<PlaceIndex> {
self.find_extra(place, [])
}
/// Locates the given place and applies `Discriminant`, if it exists in the tree.
pub fn find_discr(&self, place: PlaceRef<'_>) -> Option<PlaceIndex> { pub fn find_discr(&self, place: PlaceRef<'_>) -> Option<PlaceIndex> {
let index = self.find(place)?; self.find_extra(place, [TrackElem::Discriminant])
self.apply(index, TrackElem::Discriminant)
} }
/// Iterate over all direct children. /// Iterate over all direct children.
@ -763,14 +774,14 @@ impl Map {
/// ///
/// `tail_elem` allows to support discriminants that are not a place in MIR, but that we track /// `tail_elem` allows to support discriminants that are not a place in MIR, but that we track
/// as such. /// as such.
fn for_each_aliasing_place( pub fn for_each_aliasing_place(
&self, &self,
place: PlaceRef<'_>, place: PlaceRef<'_>,
tail_elem: Option<TrackElem>, tail_elem: Option<TrackElem>,
f: &mut impl FnMut(PlaceIndex), f: &mut impl FnMut(PlaceIndex),
) { ) {
let Some(&Some(mut index)) = self.locals.get(place.local) else { let Some(&Some(mut index)) = self.locals.get(place.local) else {
// The local is not tracked at all, nothing to invalidate. // The local is not tracked at all, so it does not alias anything.
return; return;
}; };
let elems = place let elems = place
@ -782,7 +793,7 @@ impl Map {
let Ok(elem) = elem else { return }; let Ok(elem) = elem else { return };
let sub = self.apply(index, elem); let sub = self.apply(index, elem);
if let TrackElem::Variant(..) | TrackElem::Discriminant = elem { if let TrackElem::Variant(..) | TrackElem::Discriminant = elem {
// Writing to an enum variant field invalidates the other variants and the discriminant. // Enum variant fields and enum discriminants alias each another.
self.for_each_variant_sibling(index, sub, f); self.for_each_variant_sibling(index, sub, f);
} }
if let Some(sub) = sub { if let Some(sub) = sub {
@ -795,7 +806,7 @@ impl Map {
} }
/// Invoke the given function on all the descendants of the given place, except one branch. /// Invoke the given function on all the descendants of the given place, except one branch.
pub fn for_each_variant_sibling( fn for_each_variant_sibling(
&self, &self,
parent: PlaceIndex, parent: PlaceIndex,
preserved_child: Option<PlaceIndex>, preserved_child: Option<PlaceIndex>,