Support non-scalar constants.
This commit is contained in:
parent
68c2f5ba0f
commit
6ad6b4381c
12 changed files with 259 additions and 22 deletions
|
@ -532,7 +532,7 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
|
|||
/// places that are non-overlapping or identical.
|
||||
///
|
||||
/// The target place must have been flooded before calling this method.
|
||||
fn insert_place_idx(&mut self, target: PlaceIndex, source: PlaceIndex, map: &Map) {
|
||||
pub fn insert_place_idx(&mut self, target: PlaceIndex, source: PlaceIndex, map: &Map) {
|
||||
let StateData::Reachable(values) = &mut self.0 else { return };
|
||||
|
||||
// If both places are tracked, we copy the value to the target.
|
||||
|
@ -928,6 +928,31 @@ impl Map {
|
|||
f(v)
|
||||
}
|
||||
}
|
||||
|
||||
/// Invoke a function on each value in the given place and all descendants.
|
||||
pub fn for_each_projection_value<O>(
|
||||
&self,
|
||||
root: PlaceIndex,
|
||||
value: O,
|
||||
project: &mut impl FnMut(TrackElem, &O) -> Option<O>,
|
||||
f: &mut impl FnMut(PlaceIndex, &O),
|
||||
) {
|
||||
// Fast path is there is nothing to do.
|
||||
if self.inner_values[root].is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.places[root].value_index.is_some() {
|
||||
f(root, &value)
|
||||
}
|
||||
|
||||
for child in self.children(root) {
|
||||
let elem = self.places[child].proj_elem.unwrap();
|
||||
if let Some(value) = project(elem, &value) {
|
||||
self.for_each_projection_value(child, value, project, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This is the information tracked for every [`PlaceIndex`] and is stored by [`Map`].
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue