sccs info
This commit is contained in:
parent
960ebaf899
commit
e2bf960fe1
5 changed files with 74 additions and 8 deletions
|
@ -17,7 +17,7 @@ pub(crate) mod graph;
|
||||||
/// constraints of the form `R1: R2`. Each constraint is identified by
|
/// constraints of the form `R1: R2`. Each constraint is identified by
|
||||||
/// a unique `OutlivesConstraintIndex` and you can index into the set
|
/// a unique `OutlivesConstraintIndex` and you can index into the set
|
||||||
/// (`constraint_set[i]`) to access the constraint details.
|
/// (`constraint_set[i]`) to access the constraint details.
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub(crate) struct OutlivesConstraintSet<'tcx> {
|
pub(crate) struct OutlivesConstraintSet<'tcx> {
|
||||||
outlives: IndexVec<OutlivesConstraintIndex, OutlivesConstraint<'tcx>>,
|
outlives: IndexVec<OutlivesConstraintIndex, OutlivesConstraint<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,6 +263,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut regioncx = RegionInferenceContext::new(
|
let mut regioncx = RegionInferenceContext::new(
|
||||||
|
infcx,
|
||||||
var_origins,
|
var_origins,
|
||||||
universal_regions,
|
universal_regions,
|
||||||
placeholder_indices,
|
placeholder_indices,
|
||||||
|
|
|
@ -34,6 +34,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
type_check::{free_region_relations::UniversalRegionRelations, Locations},
|
type_check::{free_region_relations::UniversalRegionRelations, Locations},
|
||||||
universal_regions::UniversalRegions,
|
universal_regions::UniversalRegions,
|
||||||
|
BorrowckInferCtxt,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod dump_mir;
|
mod dump_mir;
|
||||||
|
@ -243,6 +244,59 @@ pub enum ExtraConstraintInfo {
|
||||||
PlaceholderFromPredicate(Span),
|
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(®_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> {
|
impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
/// Creates a new region inference context with a total of
|
/// Creates a new region inference context with a total of
|
||||||
/// `num_region_variables` valid inference variables; the first N
|
/// `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
|
/// The `outlives_constraints` and `type_tests` are an initial set
|
||||||
/// of constraints produced by the MIR type check.
|
/// of constraints produced by the MIR type check.
|
||||||
pub(crate) fn new(
|
pub(crate) fn new<'cx>(
|
||||||
|
_infcx: &BorrowckInferCtxt<'cx, 'tcx>,
|
||||||
var_infos: VarInfos,
|
var_infos: VarInfos,
|
||||||
universal_regions: Rc<UniversalRegions<'tcx>>,
|
universal_regions: Rc<UniversalRegions<'tcx>>,
|
||||||
placeholder_indices: Rc<PlaceholderIndices>,
|
placeholder_indices: Rc<PlaceholderIndices>,
|
||||||
|
@ -263,6 +318,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
liveness_constraints: LivenessValues<RegionVid>,
|
liveness_constraints: LivenessValues<RegionVid>,
|
||||||
elements: &Rc<RegionValueElements>,
|
elements: &Rc<RegionValueElements>,
|
||||||
) -> Self {
|
) -> 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.
|
// Create a RegionDefinition for each inference variable.
|
||||||
let definitions: IndexVec<_, _> = var_infos
|
let definitions: IndexVec<_, _> = var_infos
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -274,6 +334,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
let fr_static = universal_regions.fr_static;
|
let fr_static = universal_regions.fr_static;
|
||||||
let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph, 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 =
|
let mut scc_values =
|
||||||
RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
|
RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ impl<N: Idx> LivenessValues<N> {
|
||||||
/// Maps from `ty::PlaceholderRegion` values that are used in the rest of
|
/// Maps from `ty::PlaceholderRegion` values that are used in the rest of
|
||||||
/// rustc to the internal `PlaceholderIndex` values that are used in
|
/// rustc to the internal `PlaceholderIndex` values that are used in
|
||||||
/// NLL.
|
/// NLL.
|
||||||
#[derive(Default)]
|
#[derive(Debug, Default)]
|
||||||
pub(crate) struct PlaceholderIndices {
|
pub(crate) struct PlaceholderIndices {
|
||||||
indices: FxIndexSet<ty::PlaceholderRegion>,
|
indices: FxIndexSet<ty::PlaceholderRegion>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,21 +21,21 @@ mod tests;
|
||||||
pub struct Sccs<N: Idx, S: Idx> {
|
pub struct Sccs<N: Idx, S: Idx> {
|
||||||
/// For each node, what is the SCC index of the SCC to which it
|
/// For each node, what is the SCC index of the SCC to which it
|
||||||
/// belongs.
|
/// belongs.
|
||||||
scc_indices: IndexVec<N, S>,
|
pub scc_indices: IndexVec<N, S>,
|
||||||
|
|
||||||
/// Data about each SCC.
|
/// 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
|
/// For each SCC, the range of `all_successors` where its
|
||||||
/// successors can be found.
|
/// successors can be found.
|
||||||
ranges: IndexVec<S, Range<usize>>,
|
pub ranges: IndexVec<S, Range<usize>>,
|
||||||
|
|
||||||
/// Contains the successors for all the Sccs, concatenated. The
|
/// Contains the successors for all the Sccs, concatenated. The
|
||||||
/// range of indices corresponding to a given SCC is found in its
|
/// range of indices corresponding to a given SCC is found in its
|
||||||
/// SccData.
|
/// SccData.
|
||||||
all_successors: Vec<S>,
|
pub all_successors: Vec<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Idx, S: Idx + Ord> Sccs<N, S> {
|
impl<N: Idx, S: Idx + Ord> Sccs<N, S> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue