about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLucas Molas <schomatis@gmail.com>2019-02-14 23:49:45 -0300
committerLucas Molas <schomatis@gmail.com>2019-02-15 21:09:53 -0300
commit4ae4e0501bdf9e6d6be06757b08f92e3553848c6 (patch)
tree43b4103dae657045031d88d68571449d5c9d74dd
parent200bc02a5e41e763175b5fa9eb97f27a472c777f (diff)
downloadrust-4ae4e0501bdf9e6d6be06757b08f92e3553848c6.tar.gz
rust-4ae4e0501bdf9e6d6be06757b08f92e3553848c6.zip
nll: remove `NllLivenessMap` from `LocalUseMap`
Extend `LocalUseMap`'s `IndexVec`s that track def/use/drop data to store the
original `Local` indexes and not the compacted `LiveVar` ones (favoring speed
and code simplicity over space). Remove the `NllLivenessMap` embedded inside it
since it's no longer needed to perform the `LiveVar`/`Local` conversion.
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs79
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs6
2 files changed, 52 insertions, 33 deletions
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
index fccd633aaa1..9b894009885 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
@@ -1,6 +1,5 @@
 use crate::borrow_check::nll::region_infer::values::{PointIndex, RegionValueElements};
-use crate::borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap};
-use crate::util::liveness::{categorize, DefUse, LiveVariableMap};
+use crate::util::liveness::{categorize, DefUse};
 use rustc::mir::visit::{PlaceContext, Visitor};
 use rustc::mir::{Local, Location, Mir};
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
@@ -9,26 +8,33 @@ use rustc_data_structures::vec_linked_list as vll;
 /// A map that cross references each local with the locations where it
 /// is defined (assigned), used, or dropped. Used during liveness
 /// computation.
-crate struct LocalUseMap<'me> {
-    liveness_map: &'me NllLivenessMap,
-
+///
+/// We keep track only of `Local`s we'll do the liveness analysis later,
+/// this means that our internal `IndexVec`s will only be sparsely populated.
+/// In the time-memory trade-off between keeping compact vectors with new
+/// indexes (and needing to continuously map the `Local` index to its compact
+/// counterpart) and having `IndexVec`s that we only use a fraction of, time
+/// (and code simplicity) was favored. The rationale is that we only keep
+/// a small number of `IndexVec`s throughout the entire analysis while, in
+/// contrast, we're accessing each `Local` *many* times.
+crate struct LocalUseMap {
     /// Head of a linked list of **definitions** of each variable --
     /// definition in this context means assignment, e.g., `x` is
     /// defined in `x = y` but not `y`; that first def is the head of
     /// a linked list that lets you enumerate all places the variable
     /// is assigned.
-    first_def_at: IndexVec<LiveVar, Option<AppearanceIndex>>,
+    first_def_at: IndexVec<Local, Option<AppearanceIndex>>,
 
     /// Head of a linked list of **uses** of each variable -- use in
     /// this context means that the existing value of the variable is
     /// read or modified. e.g., `y` is used in `x = y` but not `x`.
     /// Note that `DROP(x)` terminators are excluded from this list.
-    first_use_at: IndexVec<LiveVar, Option<AppearanceIndex>>,
+    first_use_at: IndexVec<Local, Option<AppearanceIndex>>,
 
     /// Head of a linked list of **drops** of each variable -- these
     /// are a special category of uses corresponding to the drop that
     /// we add for each local variable.
-    first_drop_at: IndexVec<LiveVar, Option<AppearanceIndex>>,
+    first_drop_at: IndexVec<Local, Option<AppearanceIndex>>,
 
     appearances: IndexVec<AppearanceIndex, Appearance>,
 }
@@ -50,55 +56,68 @@ impl vll::LinkElem for Appearance {
     }
 }
 
-impl LocalUseMap<'me> {
+impl LocalUseMap {
     crate fn build(
-        liveness_map: &'me NllLivenessMap,
+        live_locals: &Vec<Local>,
         elements: &RegionValueElements,
         mir: &Mir<'_>,
     ) -> Self {
-        let nones = IndexVec::from_elem_n(None, liveness_map.num_variables());
+        let nones = IndexVec::from_elem_n(None, mir.local_decls.len());
         let mut local_use_map = LocalUseMap {
-            liveness_map,
             first_def_at: nones.clone(),
             first_use_at: nones.clone(),
             first_drop_at: nones,
             appearances: IndexVec::new(),
         };
 
+        let mut locals_with_use_data: IndexVec<Local, bool> =
+            IndexVec::from_elem_n(false, mir.local_decls.len());
+        live_locals
+            .iter()
+            .for_each(|&local| locals_with_use_data[local] = true);
+
         LocalUseMapBuild {
             local_use_map: &mut local_use_map,
             elements,
-        }.visit_mir(mir);
+            locals_with_use_data,
+        }
+        .visit_mir(mir);
 
         local_use_map
     }
 
     crate fn defs(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
-        let live_var = self.liveness_map.from_local(local).unwrap();
-        vll::iter(self.first_def_at[live_var], &self.appearances)
+        vll::iter(self.first_def_at[local], &self.appearances)
             .map(move |aa| self.appearances[aa].point_index)
     }
 
     crate fn uses(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
-        let live_var = self.liveness_map.from_local(local).unwrap();
-        vll::iter(self.first_use_at[live_var], &self.appearances)
+        vll::iter(self.first_use_at[local], &self.appearances)
             .map(move |aa| self.appearances[aa].point_index)
     }
 
     crate fn drops(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
-        let live_var = self.liveness_map.from_local(local).unwrap();
-        vll::iter(self.first_drop_at[live_var], &self.appearances)
+        vll::iter(self.first_drop_at[local], &self.appearances)
             .map(move |aa| self.appearances[aa].point_index)
     }
 }
 
-struct LocalUseMapBuild<'me, 'map: 'me> {
-    local_use_map: &'me mut LocalUseMap<'map>,
+struct LocalUseMapBuild<'me> {
+    local_use_map: &'me mut LocalUseMap,
     elements: &'me RegionValueElements,
+
+    // Vector used in `visit_local` to signal which `Local`s do we need
+    // def/use/drop information on, constructed from `live_locals` (that
+    // contains the variables we'll do the liveness analysis for).
+    // This vector serves optimization purposes only: we could have
+    // obtained the same information from `live_locals` but we want to
+    // avoid repeatedly calling `Vec::contains()` (see `LocalUseMap` for
+    // the rationale on the time-memory trade-off we're favoring here).
+    locals_with_use_data: IndexVec<Local, bool>,
 }
 
-impl LocalUseMapBuild<'_, '_> {
-    fn insert_def(&mut self, local: LiveVar, location: Location) {
+impl LocalUseMapBuild<'_> {
+    fn insert_def(&mut self, local: Local, location: Location) {
         Self::insert(
             self.elements,
             &mut self.local_use_map.first_def_at[local],
@@ -107,7 +126,7 @@ impl LocalUseMapBuild<'_, '_> {
         );
     }
 
-    fn insert_use(&mut self, local: LiveVar, location: Location) {
+    fn insert_use(&mut self, local: Local, location: Location) {
         Self::insert(
             self.elements,
             &mut self.local_use_map.first_use_at[local],
@@ -116,7 +135,7 @@ impl LocalUseMapBuild<'_, '_> {
         );
     }
 
-    fn insert_drop(&mut self, local: LiveVar, location: Location) {
+    fn insert_drop(&mut self, local: Local, location: Location) {
         Self::insert(
             self.elements,
             &mut self.local_use_map.first_drop_at[local],
@@ -140,13 +159,13 @@ impl LocalUseMapBuild<'_, '_> {
     }
 }
 
-impl Visitor<'tcx> for LocalUseMapBuild<'_, '_> {
+impl Visitor<'tcx> for LocalUseMapBuild<'_> {
     fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, location: Location) {
-        if let Some(local_with_region) = self.local_use_map.liveness_map.from_local(local) {
+        if self.locals_with_use_data[local] {
             match categorize(context) {
-                Some(DefUse::Def) => self.insert_def(local_with_region, location),
-                Some(DefUse::Use) => self.insert_use(local_with_region, location),
-                Some(DefUse::Drop) => self.insert_drop(local_with_region, location),
+                Some(DefUse::Def) => self.insert_def(local, location),
+                Some(DefUse::Use) => self.insert_use(local, location),
+                Some(DefUse::Drop) => self.insert_drop(local, location),
                 _ => (),
             }
         }
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
index 67dcf255f56..4950d0045d3 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
@@ -46,7 +46,8 @@ pub(super) fn trace(
         return;
     }
 
-    let local_use_map = &LocalUseMap::build(liveness_map, elements, mir);
+    let live_locals: Vec<Local> = liveness_map.to_local.clone().into_iter().collect();
+    let local_use_map = &LocalUseMap::build(&live_locals, elements, mir);
 
     let cx = LivenessContext {
         typeck,
@@ -59,7 +60,6 @@ pub(super) fn trace(
         location_table,
     };
 
-    let live_locals: Vec<Local> = liveness_map.to_local.clone().into_iter().collect();
     LivenessResults::new(cx).compute_for_all_locals(live_locals);
 }
 
@@ -92,7 +92,7 @@ where
 
     /// Index indicating where each variable is assigned, used, or
     /// dropped.
-    local_use_map: &'me LocalUseMap<'me>,
+    local_use_map: &'me LocalUseMap,
 
     /// Maps between a MIR Location and a LocationIndex
     location_table: &'me LocationTable,