Skip to content

Commit 59dc201

Browse files
nikomatsakisMark-Simulacrum
authored andcommitted
optimization: use a single DepthFirstSearch instead of hashsets
Extend the `DepthFirstSearch` iterator so that it can be re-used and extended with add'l start nodes. Then replace the FxHashSets of nodes we were using in the fallback analysis with a single iterator. This way we won't re-walk portions of the graph that are reached more than once, and we also do less allocation etc.
1 parent bc2ece2 commit 59dc201

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

Diff for: compiler/rustc_typeck/src/check/fallback.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use crate::check::FnCtxt;
22
use rustc_data_structures::{
3-
fx::FxHashMap, graph::vec_graph::VecGraph, graph::WithSuccessors, stable_set::FxHashSet,
3+
fx::FxHashMap,
4+
graph::WithSuccessors,
5+
graph::{iterate::DepthFirstSearch, vec_graph::VecGraph},
6+
stable_set::FxHashSet,
47
};
58
use rustc_middle::ty::{self, Ty};
69

@@ -280,7 +283,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
280283
// type variable. These will typically default to `!`, unless
281284
// we find later that they are *also* reachable from some
282285
// other type variable outside this set.
283-
let mut roots_reachable_from_diverging = FxHashSet::default();
286+
let mut roots_reachable_from_diverging = DepthFirstSearch::new(&coercion_graph);
284287
let mut diverging_vids = vec![];
285288
let mut non_diverging_vids = vec![];
286289
for unsolved_vid in unsolved_vids {
@@ -293,16 +296,21 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
293296
);
294297
if diverging_roots.contains(&root_vid) {
295298
diverging_vids.push(unsolved_vid);
299+
roots_reachable_from_diverging.push_start_node(root_vid);
300+
296301
debug!(
297302
"calculate_diverging_fallback: root_vid={:?} reaches {:?}",
298303
root_vid,
299304
coercion_graph.depth_first_search(root_vid).collect::<Vec<_>>()
300305
);
301-
roots_reachable_from_diverging.extend(coercion_graph.depth_first_search(root_vid));
306+
307+
// drain the iterator to visit all nodes reachable from this node
308+
roots_reachable_from_diverging.complete_search();
302309
} else {
303310
non_diverging_vids.push(unsolved_vid);
304311
}
305312
}
313+
306314
debug!(
307315
"calculate_diverging_fallback: roots_reachable_from_diverging={:?}",
308316
roots_reachable_from_diverging,
@@ -312,13 +320,14 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
312320
// diverging variable, and then compute the set reachable from
313321
// N0, which we call N. These are the *non-diverging* type
314322
// variables. (Note that this set consists of "root variables".)
315-
let mut roots_reachable_from_non_diverging = FxHashSet::default();
323+
let mut roots_reachable_from_non_diverging = DepthFirstSearch::new(&coercion_graph);
316324
for &non_diverging_vid in &non_diverging_vids {
317325
let root_vid = self.infcx.root_var(non_diverging_vid);
318-
if roots_reachable_from_diverging.contains(&root_vid) {
326+
if roots_reachable_from_diverging.visited(root_vid) {
319327
continue;
320328
}
321-
roots_reachable_from_non_diverging.extend(coercion_graph.depth_first_search(root_vid));
329+
roots_reachable_from_non_diverging.push_start_node(root_vid);
330+
roots_reachable_from_non_diverging.complete_search();
322331
}
323332
debug!(
324333
"calculate_diverging_fallback: roots_reachable_from_non_diverging={:?}",
@@ -334,7 +343,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
334343
let root_vid = self.infcx.root_var(diverging_vid);
335344
let can_reach_non_diverging = coercion_graph
336345
.depth_first_search(root_vid)
337-
.any(|n| roots_reachable_from_non_diverging.contains(&n));
346+
.any(|n| roots_reachable_from_non_diverging.visited(n));
338347
if can_reach_non_diverging {
339348
debug!("fallback to (): {:?}", diverging_vid);
340349
diverging_fallback.insert(diverging_ty, self.tcx.types.unit);

0 commit comments

Comments
 (0)