Skip to content

Commit 8ecb276

Browse files
committed
Simplify creation of map
1 parent 9766ee0 commit 8ecb276

File tree

2 files changed

+26
-53
lines changed

2 files changed

+26
-53
lines changed

compiler/rustc_mir_dataflow/src/value_analysis.rs

Lines changed: 25 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ use std::fmt::{Debug, Formatter};
3636

3737
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
3838
use rustc_index::vec::IndexVec;
39-
use rustc_middle::mir::tcx::PlaceTy;
4039
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
4140
use rustc_middle::mir::*;
4241
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -552,9 +551,10 @@ impl<V: JoinSemiLattice + Clone> JoinSemiLattice for State<V> {
552551
}
553552
}
554553

555-
/// A partial mapping from `Place` to `PlaceIndex`, where some place indices have value indices.
554+
/// Partial mapping from [`Place`] to [`PlaceIndex`], where some places also have a [`ValueIndex`].
556555
///
557-
/// Some additional bookkeeping is done to speed up traversal:
556+
/// This data structure essentially maintains a tree of places and their projections. Some
557+
/// additional bookkeeping is done, to speed up traversal over this tree:
558558
/// - For iteration, every [`PlaceInfo`] contains an intrusive linked list of its children.
559559
/// - To directly get the child for a specific projection, there is a `projections` map.
560560
#[derive(Debug)]
@@ -578,7 +578,8 @@ impl Map {
578578
/// Returns a map that only tracks places whose type passes the filter.
579579
///
580580
/// This is currently the only way to create a [`Map`]. The way in which the tracked places are
581-
/// chosen is an implementation detail and may not be relied upon.
581+
/// chosen is an implementation detail and may not be relied upon (other than that their type
582+
/// passes the filter).
582583
#[instrument(skip_all, level = "debug")]
583584
pub fn from_filter<'tcx>(
584585
tcx: TyCtxt<'tcx>,
@@ -599,6 +600,7 @@ impl Map {
599600
mut filter: impl FnMut(Ty<'tcx>) -> bool,
600601
exclude: &FxHashSet<Place<'tcx>>,
601602
) {
603+
// We use this vector as stack, pushing and popping projections.
602604
let mut projection = Vec::new();
603605
for (local, decl) in body.local_decls.iter_enumerated() {
604606
self.register_with_filter_rec(
@@ -612,6 +614,9 @@ impl Map {
612614
}
613615
}
614616

617+
/// Register fields of the given (local, projection) place.
618+
///
619+
/// Invariant: The projection must only contain fields.
615620
fn register_with_filter_rec<'tcx>(
616621
&mut self,
617622
tcx: TyCtxt<'tcx>,
@@ -626,10 +631,19 @@ impl Map {
626631
return;
627632
}
628633

629-
if filter(ty) {
630-
// This might fail if `ty` is not scalar.
631-
let _ = self.register_with_ty(local, projection, ty);
634+
// Note: The framework supports only scalars for now.
635+
if filter(ty) && ty.is_scalar() {
636+
// We know that the projection only contains trackable elements.
637+
let place = self.make_place(local, projection).unwrap();
638+
639+
// Allocate a value slot if it doesn't have one.
640+
if self.places[place].value_index.is_none() {
641+
self.places[place].value_index = Some(self.value_count.into());
642+
self.value_count += 1;
643+
}
632644
}
645+
646+
// Recurse with all fields of this place.
633647
iter_fields(ty, tcx, |variant, field, ty| {
634648
if variant.is_some() {
635649
// Downcasts are currently not supported.
@@ -668,59 +682,17 @@ impl Map {
668682
Ok(index)
669683
}
670684

671-
#[allow(unused)]
672-
fn register<'tcx>(
673-
&mut self,
674-
local: Local,
675-
projection: &[PlaceElem<'tcx>],
676-
decls: &impl HasLocalDecls<'tcx>,
677-
tcx: TyCtxt<'tcx>,
678-
) -> Result<(), ()> {
679-
projection
680-
.iter()
681-
.fold(PlaceTy::from_ty(decls.local_decls()[local].ty), |place_ty, &elem| {
682-
place_ty.projection_ty(tcx, elem)
683-
});
684-
685-
let place_ty = Place::ty_from(local, projection, decls, tcx);
686-
if place_ty.variant_index.is_some() {
687-
return Err(());
688-
}
689-
self.register_with_ty(local, projection, place_ty.ty)
690-
}
691-
692-
/// Tries to track the given place. Fails if type is non-scalar or projection is not trackable.
693-
fn register_with_ty<'tcx>(
694-
&mut self,
695-
local: Local,
696-
projection: &[PlaceElem<'tcx>],
697-
ty: Ty<'tcx>,
698-
) -> Result<(), ()> {
699-
if !ty.is_scalar() {
700-
// Currently, only scalar types are allowed, because they are atomic
701-
// and therefore do not require invalidation of parent places.
702-
return Err(());
703-
}
704-
705-
let place = self.make_place(local, projection)?;
706-
707-
// Allocate a value slot if it doesn't have one.
708-
if self.places[place].value_index.is_none() {
709-
self.places[place].value_index = Some(self.value_count.into());
710-
self.value_count += 1;
711-
}
712-
713-
Ok(())
714-
}
715-
685+
/// Returns the number of tracked places, i.e., those for which a value can be stored.
716686
pub fn tracked_places(&self) -> usize {
717687
self.value_count
718688
}
719689

690+
/// Applies a single projection element, yielding the corresponding child.
720691
pub fn apply(&self, place: PlaceIndex, elem: TrackElem) -> Option<PlaceIndex> {
721692
self.projections.get(&(place, elem)).copied()
722693
}
723694

695+
/// Locates the given place, if it exists in the tree.
724696
pub fn find(&self, place: PlaceRef<'_>) -> Option<PlaceIndex> {
725697
let mut index = *self.locals.get(place.local)?.as_ref()?;
726698

@@ -736,6 +708,7 @@ impl Map {
736708
Children::new(self, parent)
737709
}
738710

711+
/// Invoke a function on the given place and all descendants.
739712
pub fn preorder_invoke(&self, root: PlaceIndex, f: &mut impl FnMut(PlaceIndex)) {
740713
f(root);
741714
for child in self.children(root) {

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
105105
FlatSet::Top => FlatSet::Top,
106106
FlatSet::Elem(overflow) => {
107107
if overflow {
108-
// Overflow cannot be reliable propagated. See: https://github.com/rust-lang/rust/pull/101168#issuecomment-1288091446
108+
// Overflow cannot be reliably propagated. See: https://github.com/rust-lang/rust/pull/101168#issuecomment-1288091446
109109
FlatSet::Top
110110
} else {
111111
self.wrap_scalar(Scalar::from_bool(false), self.tcx.types.bool)

0 commit comments

Comments
 (0)