about summary refs log tree commit diff
path: root/compiler/rustc_mir_dataflow/src/value_analysis.rs
diff options
context:
space:
mode:
authorJannis Christopher Köhl <mail@koehl.dev>2022-11-12 14:57:14 +0100
committerJannis Christopher Köhl <mail@koehl.dev>2022-11-12 14:57:14 +0100
commit2e034dc68cb4d593f564f5ff8c444be5d12fc95b (patch)
treeb09153566f23935f503af344d6dd3160491e1ac7 /compiler/rustc_mir_dataflow/src/value_analysis.rs
parentb3f648958d4f556bcceedd8c1d9b0dedb83c7bf9 (diff)
downloadrust-2e034dc68cb4d593f564f5ff8c444be5d12fc95b.tar.gz
rust-2e034dc68cb4d593f564f5ff8c444be5d12fc95b.zip
Exclude locals completely, instead of individual places
Diffstat (limited to 'compiler/rustc_mir_dataflow/src/value_analysis.rs')
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs47
1 files changed, 18 insertions, 29 deletions
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index 0f3b952ceec..85a35c13fd9 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -34,7 +34,7 @@
 
 use std::fmt::{Debug, Formatter};
 
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashMap;
 use rustc_index::vec::IndexVec;
 use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
@@ -587,7 +587,8 @@ impl Map {
         filter: impl FnMut(Ty<'tcx>) -> bool,
     ) -> Self {
         let mut map = Self::new();
-        map.register_with_filter(tcx, body, filter, &escaped_places(body));
+        let exclude = excluded_locals(body);
+        map.register_with_filter(tcx, body, filter, &exclude);
         debug!("registered {} places ({} nodes in total)", map.value_count, map.places.len());
         map
     }
@@ -598,19 +599,14 @@ impl Map {
         tcx: TyCtxt<'tcx>,
         body: &Body<'tcx>,
         mut filter: impl FnMut(Ty<'tcx>) -> bool,
-        exclude: &FxHashSet<Place<'tcx>>,
+        exclude: &IndexVec<Local, bool>,
     ) {
         // We use this vector as stack, pushing and popping projections.
         let mut projection = Vec::new();
         for (local, decl) in body.local_decls.iter_enumerated() {
-            self.register_with_filter_rec(
-                tcx,
-                local,
-                &mut projection,
-                decl.ty,
-                &mut filter,
-                exclude,
-            );
+            if !exclude[local] {
+                self.register_with_filter_rec(tcx, local, &mut projection, decl.ty, &mut filter);
+            }
         }
     }
 
@@ -624,17 +620,10 @@ impl Map {
         projection: &mut Vec<PlaceElem<'tcx>>,
         ty: Ty<'tcx>,
         filter: &mut impl FnMut(Ty<'tcx>) -> bool,
-        exclude: &FxHashSet<Place<'tcx>>,
     ) {
-        let place = Place { local, projection: tcx.intern_place_elems(projection) };
-        if exclude.contains(&place) {
-            // This will also exclude all projections of the excluded place.
-            return;
-        }
-
         // Note: The framework supports only scalars for now.
         if filter(ty) && ty.is_scalar() {
-            trace!("registering place: {:?}", place);
+            // trace!("registering place {:?}", PlaceRef { local, projection: &*projection });
 
             // We know that the projection only contains trackable elements.
             let place = self.make_place(local, projection).unwrap();
@@ -653,7 +642,7 @@ impl Map {
                 return;
             }
             projection.push(PlaceElem::Field(field, ty));
-            self.register_with_filter_rec(tcx, local, projection, ty, filter, exclude);
+            self.register_with_filter_rec(tcx, local, projection, ty, filter);
             projection.pop();
         });
     }
@@ -835,27 +824,27 @@ fn iter_fields<'tcx>(
     }
 }
 
-/// Returns all places, that have their reference or address taken.
-///
-/// This includes shared references, and also drops and `InlineAsm` out parameters.
-fn escaped_places<'tcx>(body: &Body<'tcx>) -> FxHashSet<Place<'tcx>> {
-    struct Collector<'tcx> {
-        result: FxHashSet<Place<'tcx>>,
+/// Returns all locals with projections that have their reference or address taken.
+fn excluded_locals<'tcx>(body: &Body<'tcx>) -> IndexVec<Local, bool> {
+    struct Collector {
+        result: IndexVec<Local, bool>,
     }
 
-    impl<'tcx> Visitor<'tcx> for Collector<'tcx> {
+    impl<'tcx> Visitor<'tcx> for Collector {
         fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
             if context.is_borrow()
                 || context.is_address_of()
                 || context.is_drop()
                 || context == PlaceContext::MutatingUse(MutatingUseContext::AsmOutput)
             {
-                self.result.insert(*place);
+                // A pointer to a place could be used to access other places with the same local,
+                // hence we have to exclude the local completely.
+                self.result[place.local] = true;
             }
         }
     }
 
-    let mut collector = Collector { result: FxHashSet::default() };
+    let mut collector = Collector { result: IndexVec::from_elem(false, &body.local_decls) };
     collector.visit_body(body);
     collector.result
 }