about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/borrow_check/nll/mod.rs1
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs94
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs85
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs8
4 files changed, 71 insertions, 117 deletions
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 84fdbb9423e..2d3800dd1dd 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -2,7 +2,6 @@ use crate::borrow_check::borrow_set::BorrowSet;
 use crate::borrow_check::location::{LocationIndex, LocationTable};
 use crate::borrow_check::nll::facts::AllFactsExt;
 use crate::borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints};
-use crate::borrow_check::nll::type_check::liveness::liveness_map::NllLivenessMap;
 use crate::borrow_check::nll::region_infer::values::RegionValueElements;
 use crate::dataflow::indexes::BorrowIndex;
 use crate::dataflow::move_paths::MoveData;
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs
deleted file mode 100644
index b9f9d83161b..00000000000
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs
+++ /dev/null
@@ -1,94 +0,0 @@
-//! For the NLL computation, we need to compute liveness, but only for those
-//! local variables whose types contain regions. The others are not of interest
-//! to us. This file defines a new index type (LiveVar) that indexes into
-//! a list of "variables whose type contain regions". It also defines a map from
-//! Local to LiveVar and vice versa -- this map can be given to the
-//! liveness code so that it only operates over variables with regions in their
-//! types, instead of all variables.
-
-use crate::borrow_check::nll::ToRegionVid;
-use crate::borrow_check::nll::facts::{AllFacts, AllFactsExt};
-use crate::util::liveness::LiveVariableMap;
-use rustc::mir::{Local, Mir};
-use rustc::ty::{RegionVid, TyCtxt};
-use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::indexed_vec::{Idx, IndexVec};
-
-/// Map between Local and LiveVar indices: the purpose of this
-/// map is to define the subset of local variables for which we need
-/// to do a liveness computation. We only need to compute whether a
-/// variable `X` is live if that variable contains some region `R` in
-/// its type where `R` is not known to outlive a free region (i.e.,
-/// where `R` may be valid for just a subset of the fn body).
-crate struct NllLivenessMap {
-    /// For each local variable, contains `Some(i)` if liveness is
-    /// needed for this variable.
-    pub from_local: IndexVec<Local, Option<LiveVar>>,
-
-    /// For each `LiveVar`, maps back to the original `Local` index.
-    pub to_local: IndexVec<LiveVar, Local>,
-}
-
-impl LiveVariableMap for NllLivenessMap {
-    fn from_local(&self, local: Local) -> Option<Self::LiveVar> {
-        self.from_local[local]
-    }
-
-    type LiveVar = LiveVar;
-
-    fn from_live_var(&self, local: Self::LiveVar) -> Local {
-        self.to_local[local]
-    }
-
-    fn num_variables(&self) -> usize {
-        self.to_local.len()
-    }
-}
-
-impl NllLivenessMap {
-    crate fn compute(
-        tcx: TyCtxt<'_, '_, 'tcx>,
-        free_regions: &FxHashSet<RegionVid>,
-        mir: &Mir<'tcx>,
-    ) -> Self {
-        let mut to_local = IndexVec::default();
-        let facts_enabled = AllFacts::enabled(tcx);
-        let from_local: IndexVec<Local, Option<_>> = mir.local_decls
-            .iter_enumerated()
-            .map(|(local, local_decl)| {
-                if tcx.all_free_regions_meet(&local_decl.ty, |r| {
-                    free_regions.contains(&r.to_region_vid())
-                }) && !facts_enabled {
-                    // If all the regions in the type are free regions
-                    // (or there are no regions), then we don't need
-                    // to track liveness for this variable.
-                    None
-                } else {
-                    Some(to_local.push(local))
-                }
-            })
-            .collect();
-
-        debug!("{} total variables", mir.local_decls.len());
-        debug!("{} variables need liveness", to_local.len());
-        debug!("{} regions outlive free regions", free_regions.len());
-
-        Self {
-            from_local,
-            to_local,
-        }
-    }
-
-    /// Returns `true` if there are no local variables that need liveness computation.
-    crate fn is_empty(&self) -> bool {
-        self.to_local.is_empty()
-    }
-}
-
-/// Index given to each local variable for which we need to
-/// compute liveness information. For many locals, we are able to
-/// skip liveness information: for example, those variables whose
-/// types contain no regions.
-newtype_index! {
-    pub struct LiveVar { .. }
-}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
index 28a8cad8ca2..960e75048fa 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
@@ -1,19 +1,19 @@
 use crate::borrow_check::location::LocationTable;
-use crate::borrow_check::nll::region_infer::values::RegionValueElements;
 use crate::borrow_check::nll::constraints::ConstraintSet;
-use crate::borrow_check::nll::NllLivenessMap;
+use crate::borrow_check::nll::facts::{AllFacts, AllFactsExt};
+use crate::borrow_check::nll::region_infer::values::RegionValueElements;
 use crate::borrow_check::nll::universal_regions::UniversalRegions;
+use crate::borrow_check::nll::ToRegionVid;
 use crate::dataflow::move_paths::MoveData;
-use crate::dataflow::MaybeInitializedPlaces;
 use crate::dataflow::FlowAtLocation;
-use rustc::mir::Mir;
-use rustc::ty::RegionVid;
+use crate::dataflow::MaybeInitializedPlaces;
+use rustc::mir::{Local, Mir};
+use rustc::ty::{RegionVid, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
 use std::rc::Rc;
 
 use super::TypeChecker;
 
-crate mod liveness_map;
 mod local_use_map;
 mod trace;
 
@@ -34,16 +34,71 @@ pub(super) fn generate<'gcx, 'tcx>(
     location_table: &LocationTable,
 ) {
     debug!("liveness::generate");
-    let free_regions = {
-        let borrowck_context = typeck.borrowck_context.as_ref().unwrap();
-        regions_that_outlive_free_regions(
-            typeck.infcx.num_region_vars(),
-            &borrowck_context.universal_regions,
-            &borrowck_context.constraints.outlives_constraints,
-        )
+
+    let live_locals: Vec<Local> = if AllFacts::enabled(typeck.tcx()) {
+        // If "dump facts from NLL analysis" was requested perform
+        // the liveness analysis for all `Local`s. This case opens
+        // the possibility of the variables being analyzed in `trace`
+        // to be *any* `Local`, not just the "live" ones, so we can't
+        // make any assumptions past this point as to the characteristics
+        // of the `live_locals`.
+        // FIXME: Review "live" terminology past this point, we should
+        // not be naming the `Local`s as live.
+        mir.local_decls.indices().collect()
+    } else {
+        let free_regions = {
+            let borrowck_context = typeck.borrowck_context.as_ref().unwrap();
+            regions_that_outlive_free_regions(
+                typeck.infcx.num_region_vars(),
+                &borrowck_context.universal_regions,
+                &borrowck_context.constraints.outlives_constraints,
+            )
+        };
+        compute_live_locals(typeck.tcx(), &free_regions, mir)
     };
-    let liveness_map = NllLivenessMap::compute(typeck.tcx(), &free_regions, mir);
-    trace::trace(typeck, mir, elements, flow_inits, move_data, &liveness_map, location_table);
+
+    if !live_locals.is_empty() {
+        trace::trace(
+            typeck,
+            mir,
+            elements,
+            flow_inits,
+            move_data,
+            live_locals,
+            location_table,
+        );
+    }
+}
+
+// The purpose of `compute_live_locals` is to define the subset of `Local`
+// variables for which we need to do a liveness computation. We only need
+// to compute whether a variable `X` is live if that variable contains
+// some region `R` in its type where `R` is not known to outlive a free
+// region (i.e., where `R` may be valid for just a subset of the fn body).
+fn compute_live_locals(
+    tcx: TyCtxt<'_, '_, 'tcx>,
+    free_regions: &FxHashSet<RegionVid>,
+    mir: &Mir<'tcx>,
+) -> Vec<Local> {
+    let live_locals: Vec<Local> = mir
+        .local_decls
+        .iter_enumerated()
+        .filter_map(|(local, local_decl)| {
+            if tcx.all_free_regions_meet(&local_decl.ty, |r| {
+                free_regions.contains(&r.to_region_vid())
+            }) {
+                None
+            } else {
+                Some(local)
+            }
+        })
+        .collect();
+
+    debug!("{} total variables", mir.local_decls.len());
+    debug!("{} variables need liveness", live_locals.len());
+    debug!("{} regions outlive free regions", free_regions.len());
+
+    live_locals
 }
 
 /// Computes all regions that are (currently) known to outlive free
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 4950d0045d3..f0df7070e6b 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
@@ -1,6 +1,5 @@
 use crate::borrow_check::location::LocationTable;
 use crate::borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements};
-use crate::borrow_check::nll::type_check::liveness::liveness_map::NllLivenessMap;
 use crate::borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap;
 use crate::borrow_check::nll::type_check::NormalizeLocation;
 use crate::borrow_check::nll::type_check::TypeChecker;
@@ -37,16 +36,11 @@ pub(super) fn trace(
     elements: &Rc<RegionValueElements>,
     flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
     move_data: &MoveData<'tcx>,
-    liveness_map: &NllLivenessMap,
+    live_locals: Vec<Local>,
     location_table: &LocationTable,
 ) {
     debug!("trace()");
 
-    if liveness_map.is_empty() {
-        return;
-    }
-
-    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 {