about summary refs log tree commit diff
diff options
context:
space:
mode:
authorb-naber <bn263@gmx.de>2022-11-09 21:21:36 +0100
committerb-naber <b_naber@gmx.de>2023-02-19 22:12:12 +0000
commite2bf960fe1c011e75cf0d6a06d3f955444d11043 (patch)
treec72c41cd950b697e5b67b70e70cc1c3ea0bcbf0d
parent960ebaf899cfceddf7edaf936f460491dcbf4733 (diff)
downloadrust-e2bf960fe1c011e75cf0d6a06d3f955444d11043.tar.gz
rust-e2bf960fe1c011e75cf0d6a06d3f955444d11043.zip
sccs info
-rw-r--r--compiler/rustc_borrowck/src/constraints/mod.rs2
-rw-r--r--compiler/rustc_borrowck/src/nll.rs1
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs67
-rw-r--r--compiler/rustc_borrowck/src/region_infer/values.rs2
-rw-r--r--compiler/rustc_data_structures/src/graph/scc/mod.rs10
5 files changed, 74 insertions, 8 deletions
diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs
index 1f0b8adeaf1..f370c02161b 100644
--- a/compiler/rustc_borrowck/src/constraints/mod.rs
+++ b/compiler/rustc_borrowck/src/constraints/mod.rs
@@ -17,7 +17,7 @@ pub(crate) mod graph;
 /// constraints of the form `R1: R2`. Each constraint is identified by
 /// a unique `OutlivesConstraintIndex` and you can index into the set
 /// (`constraint_set[i]`) to access the constraint details.
-#[derive(Clone, Default)]
+#[derive(Clone, Debug, Default)]
 pub(crate) struct OutlivesConstraintSet<'tcx> {
     outlives: IndexVec<OutlivesConstraintIndex, OutlivesConstraint<'tcx>>,
 }
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index c3301ac1442..28d49c19c75 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -263,6 +263,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
     }
 
     let mut regioncx = RegionInferenceContext::new(
+        infcx,
         var_origins,
         universal_regions,
         placeholder_indices,
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 83fdb6066c6..66d2850c67b 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -34,6 +34,7 @@ use crate::{
     },
     type_check::{free_region_relations::UniversalRegionRelations, Locations},
     universal_regions::UniversalRegions,
+    BorrowckInferCtxt,
 };
 
 mod dump_mir;
@@ -243,6 +244,59 @@ pub enum ExtraConstraintInfo {
     PlaceholderFromPredicate(Span),
 }
 
+#[cfg(debug_assertions)]
+#[instrument(skip(infcx, sccs), level = "debug")]
+fn sccs_info<'cx, 'tcx>(
+    infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>,
+    sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
+) {
+    use crate::renumber::RegionCtxt;
+
+    let var_to_origin = infcx.reg_var_to_origin.borrow();
+    let num_components = sccs.scc_data.ranges.len();
+    let mut components = vec![FxHashSet::default(); num_components];
+
+    for (reg_var_idx, scc_idx) in sccs.scc_indices.iter().enumerate() {
+        let reg_var = ty::RegionVid::from_usize(reg_var_idx);
+        let origin = var_to_origin.get(&reg_var).unwrap_or_else(|| &RegionCtxt::Unknown);
+        components[scc_idx.as_usize()].insert(*origin);
+    }
+
+    debug!(
+        "strongly connected components: {:#?}",
+        components
+            .iter()
+            .enumerate()
+            .map(|(idx, origin)| { (ConstraintSccIndex::from_usize(idx), origin) })
+            .collect::<Vec<_>>()
+    );
+
+    // Now let's calculate the best representative for each component
+    let components_representatives = components
+        .into_iter()
+        .enumerate()
+        .map(|(scc_idx, region_ctxts)| {
+            let repr = region_ctxts
+                .into_iter()
+                .max_by(|x, y| x._preference_value().cmp(&y._preference_value()))
+                .unwrap();
+
+            (ConstraintSccIndex::from_usize(scc_idx), repr)
+        })
+        .collect::<FxHashMap<_, _>>();
+
+    let mut scc_node_to_edges = FxHashMap::default();
+    for (scc_idx, repr) in components_representatives.iter() {
+        let edges_range = sccs.scc_data.ranges[*scc_idx].clone();
+        let edges = &sccs.scc_data.all_successors[edges_range];
+        let edge_representatives =
+            edges.iter().map(|scc_idx| components_representatives[scc_idx]).collect::<Vec<_>>();
+        scc_node_to_edges.insert((scc_idx, repr), edge_representatives);
+    }
+
+    debug!("SCC edges {:#?}", scc_node_to_edges);
+}
+
 impl<'tcx> RegionInferenceContext<'tcx> {
     /// Creates a new region inference context with a total of
     /// `num_region_variables` valid inference variables; the first N
@@ -251,7 +305,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ///
     /// The `outlives_constraints` and `type_tests` are an initial set
     /// of constraints produced by the MIR type check.
-    pub(crate) fn new(
+    pub(crate) fn new<'cx>(
+        _infcx: &BorrowckInferCtxt<'cx, 'tcx>,
         var_infos: VarInfos,
         universal_regions: Rc<UniversalRegions<'tcx>>,
         placeholder_indices: Rc<PlaceholderIndices>,
@@ -263,6 +318,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         liveness_constraints: LivenessValues<RegionVid>,
         elements: &Rc<RegionValueElements>,
     ) -> Self {
+        debug!("universal_regions: {:#?}", universal_regions);
+        debug!("outlives constraints: {:#?}", outlives_constraints);
+        debug!("placeholder_indices: {:#?}", placeholder_indices);
+        debug!("type tests: {:#?}", type_tests);
+
         // Create a RegionDefinition for each inference variable.
         let definitions: IndexVec<_, _> = var_infos
             .iter()
@@ -274,6 +334,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         let fr_static = universal_regions.fr_static;
         let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph, fr_static));
 
+        #[cfg(debug_assertions)]
+        {
+            sccs_info(_infcx, constraint_sccs.clone());
+        }
+
         let mut scc_values =
             RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
 
diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs
index 6a3748fded5..c361357ca21 100644
--- a/compiler/rustc_borrowck/src/region_infer/values.rs
+++ b/compiler/rustc_borrowck/src/region_infer/values.rs
@@ -181,7 +181,7 @@ impl<N: Idx> LivenessValues<N> {
 /// Maps from `ty::PlaceholderRegion` values that are used in the rest of
 /// rustc to the internal `PlaceholderIndex` values that are used in
 /// NLL.
-#[derive(Default)]
+#[derive(Debug, Default)]
 pub(crate) struct PlaceholderIndices {
     indices: FxIndexSet<ty::PlaceholderRegion>,
 }
diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs
index c8e66eb672c..e2fe5285aad 100644
--- a/compiler/rustc_data_structures/src/graph/scc/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs
@@ -21,21 +21,21 @@ mod tests;
 pub struct Sccs<N: Idx, S: Idx> {
     /// For each node, what is the SCC index of the SCC to which it
     /// belongs.
-    scc_indices: IndexVec<N, S>,
+    pub scc_indices: IndexVec<N, S>,
 
     /// Data about each SCC.
-    scc_data: SccData<S>,
+    pub scc_data: SccData<S>,
 }
 
-struct SccData<S: Idx> {
+pub struct SccData<S: Idx> {
     /// For each SCC, the range of `all_successors` where its
     /// successors can be found.
-    ranges: IndexVec<S, Range<usize>>,
+    pub ranges: IndexVec<S, Range<usize>>,
 
     /// Contains the successors for all the Sccs, concatenated. The
     /// range of indices corresponding to a given SCC is found in its
     /// SccData.
-    all_successors: Vec<S>,
+    pub all_successors: Vec<S>,
 }
 
 impl<N: Idx, S: Idx + Ord> Sccs<N, S> {