Skip to content

Commit cb9458d

Browse files
committed
sccs are computed in dependency order
We don't need the `scc_dependency_order` vector, `all_sccs` is already in dependency order.
1 parent c7526fe commit cb9458d

File tree

2 files changed

+10
-53
lines changed
  • src
    • librustc_data_structures/graph/scc
    • librustc_mir/borrow_check/region_infer

2 files changed

+10
-53
lines changed

src/librustc_data_structures/graph/scc/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ impl<N: Idx, S: Idx> Sccs<N, S> {
4747
}
4848

4949
/// Returns an iterator over the SCCs in the graph.
50+
///
51+
/// The SCCs will be iterated in **dependency order** (or **post order**),
52+
/// meaning that if `S1 -> S2`, we will visit `S2` first and `S1` after.
53+
/// This is convenient when the edges represent dependencies: when you visit
54+
/// `S1`, the value for `S2` will already have been computed.
5055
pub fn all_sccs(&self) -> impl Iterator<Item = S> {
5156
(0..self.scc_data.len()).map(S::new)
5257
}

src/librustc_mir/borrow_check/region_infer/mod.rs

+5-53
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use rustc_data_structures::frozen::Frozen;
66
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
77
use rustc_data_structures::graph::scc::Sccs;
88
use rustc_hir::def_id::DefId;
9-
use rustc_index::bit_set::BitSet;
109
use rustc_index::vec::IndexVec;
1110
use rustc_infer::infer::canonical::QueryOutlivesConstraint;
1211
use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound};
@@ -67,12 +66,6 @@ pub struct RegionInferenceContext<'tcx> {
6766
/// compute the values of each region.
6867
constraint_sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
6968

70-
/// SCCs in "dependency order" (or "post order"), meaning that if S1 -> S2,
71-
/// then S2 appears first. If you process the SCCs in this order, then you
72-
/// are always ensured that when you proces a given SCC, all of its
73-
/// successors have been processed.
74-
scc_dependency_order: Vec<ConstraintSccIndex>,
75-
7669
/// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if
7770
/// `B: A`. This is used to compute the universal regions that are required
7871
/// to outlive a given SCC. Computed lazily.
@@ -283,10 +276,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
283276
scc_values.merge_liveness(scc, region, &liveness_constraints);
284277
}
285278

286-
let scc_dependency_order = Self::compute_scc_dependency_order(&constraint_sccs);
287-
288-
let scc_universes =
289-
Self::compute_scc_universes(&constraint_sccs, &scc_dependency_order, &definitions);
279+
let scc_universes = Self::compute_scc_universes(&constraint_sccs, &definitions);
290280

291281
let scc_representatives = Self::compute_scc_representatives(&constraint_sccs, &definitions);
292282

@@ -299,7 +289,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
299289
constraints,
300290
constraint_graph,
301291
constraint_sccs,
302-
scc_dependency_order,
303292
rev_scc_graph: None,
304293
member_constraints,
305294
member_constraints_applied: Vec::new(),
@@ -317,43 +306,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
317306
result
318307
}
319308

320-
/// Returns a vector of all scc-ids in "dependency" or "post order". See the
321-
/// `scc_dependency_order` field for more details.
322-
fn compute_scc_dependency_order(
323-
constraints_scc: &Sccs<RegionVid, ConstraintSccIndex>,
324-
) -> Vec<ConstraintSccIndex> {
325-
let mut visited = &mut BitSet::new_empty(constraints_scc.num_sccs());
326-
let mut output = vec![];
327-
328-
for scc in constraints_scc.all_sccs() {
329-
Self::compute_scc_dependency_order_if_new(
330-
constraints_scc,
331-
scc,
332-
&mut visited,
333-
&mut output,
334-
);
335-
}
336-
337-
output
338-
}
339-
340-
fn compute_scc_dependency_order_if_new(
341-
constraints_scc: &Sccs<RegionVid, ConstraintSccIndex>,
342-
index: ConstraintSccIndex,
343-
visited: &mut BitSet<ConstraintSccIndex>,
344-
output: &mut Vec<ConstraintSccIndex>,
345-
) {
346-
if !visited.insert(index) {
347-
return;
348-
}
349-
350-
for &succ in constraints_scc.successors(index) {
351-
Self::compute_scc_dependency_order_if_new(constraints_scc, succ, visited, output);
352-
}
353-
354-
output.push(index);
355-
}
356-
357309
/// Each SCC is the combination of many region variables which
358310
/// have been equated. Therefore, we can associate a universe with
359311
/// each SCC which is minimum of all the universes of its
@@ -363,7 +315,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
363315
/// the minimum, or narrowest, universe.
364316
fn compute_scc_universes(
365317
constraint_sccs: &Sccs<RegionVid, ConstraintSccIndex>,
366-
scc_dependency_order: &[ConstraintSccIndex],
367318
definitions: &IndexVec<RegionVid, RegionDefinition<'tcx>>,
368319
) -> IndexVec<ConstraintSccIndex, ty::UniverseIndex> {
369320
let num_sccs = constraint_sccs.num_sccs();
@@ -420,7 +371,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
420371
// constraint lowers the universe of `R1` to `U0`, which in turn
421372
// means that the `R1: !1` constraint will (later) cause
422373
// `R1` to become `'static`.
423-
for &scc_a in scc_dependency_order {
374+
for scc_a in constraint_sccs.all_sccs() {
424375
for &scc_b in constraint_sccs.successors(scc_a) {
425376
let scc_universe_a = scc_universes[scc_a];
426377
let scc_universe_b = scc_universes[scc_b];
@@ -664,8 +615,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
664615
// SCC. For each SCC, we visit its successors and compute
665616
// their values, then we union all those values to get our
666617
// own.
667-
for i in 0..self.scc_dependency_order.len() {
668-
self.compute_value_for_scc(self.scc_dependency_order[i]);
618+
let constraint_sccs = self.constraint_sccs.clone();
619+
for scc in constraint_sccs.all_sccs() {
620+
self.compute_value_for_scc(scc);
669621
}
670622

671623
// Sort the applied member constraints so we can binary search

0 commit comments

Comments
 (0)