Skip to content

Commit c06df08

Browse files
Use a single map for the CurrentDepGraph
An IndexMap instead of a HashMap and IndexVec is used. Internally this is much the same, but wrapping the two into one data structure is less prone to accidents of updating just one and is cleaner.
1 parent 7870050 commit c06df08

File tree

3 files changed

+32
-35
lines changed

3 files changed

+32
-35
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3068,6 +3068,7 @@ dependencies = [
30683068
"chalk-engine",
30693069
"fmt_macros",
30703070
"graphviz",
3071+
"indexmap",
30713072
"jobserver",
30723073
"log",
30733074
"measureme",

src/librustc/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ chalk-engine = { version = "0.9.0", default-features=false }
3737
rustc_fs_util = { path = "../librustc_fs_util" }
3838
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
3939
measureme = "0.3"
40+
indexmap = "1"

src/librustc/dep_graph/graph.rs

+30-35
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use errors::Diagnostic;
22
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
3+
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxHashSet};
44
use rustc_index::vec::{Idx, IndexVec};
55
use smallvec::SmallVec;
66
use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, Ordering};
77
use std::env;
88
use std::hash::Hash;
9-
use std::collections::hash_map::Entry;
9+
use indexmap::map::Entry;
1010
use std::mem;
1111
use crate::ty::{self, TyCtxt};
1212
use crate::util::common::{ProfileQueriesMsg, profq_msg};
@@ -123,12 +123,12 @@ impl DepGraph {
123123

124124
pub fn query(&self) -> DepGraphQuery {
125125
let current_dep_graph = self.data.as_ref().unwrap().current.borrow();
126-
let nodes: Vec<_> = current_dep_graph.data.iter().map(|n| n.node).collect();
126+
let nodes: Vec<_> = current_dep_graph.data.values().map(|n| n.node).collect();
127127
let mut edges = Vec::new();
128-
for (from, edge_targets) in current_dep_graph.data.iter()
128+
for (from, edge_targets) in current_dep_graph.data.values()
129129
.map(|d| (d.node, &d.edges)) {
130130
for &edge_target in edge_targets.iter() {
131-
let to = current_dep_graph.data[edge_target].node;
131+
let to = *current_dep_graph.data.get_index(edge_target.index()).unwrap().0;
132132
edges.push((from, to));
133133
}
134134
}
@@ -397,7 +397,8 @@ impl DepGraph {
397397
pub fn read(&self, v: DepNode) {
398398
if let Some(ref data) = self.data {
399399
let current = data.current.borrow_mut();
400-
if let Some(&dep_node_index) = current.node_to_node_index.get(&v) {
400+
if let Some((dep_node_index, _, _)) = current.data.get_full(&v) {
401+
let dep_node_index = DepNodeIndex::from_usize(dep_node_index);
401402
std::mem::drop(current);
402403
data.read_index(dep_node_index);
403404
} else {
@@ -415,21 +416,21 @@ impl DepGraph {
415416

416417
#[inline]
417418
pub fn dep_node_index_of(&self, dep_node: &DepNode) -> DepNodeIndex {
418-
self.data
419+
DepNodeIndex::from_usize(self.data
419420
.as_ref()
420421
.unwrap()
421422
.current
422423
.borrow_mut()
423-
.node_to_node_index
424-
.get(dep_node)
425-
.cloned()
424+
.data
425+
.get_full(dep_node)
426426
.unwrap()
427+
.0)
427428
}
428429

429430
#[inline]
430431
pub fn dep_node_exists(&self, dep_node: &DepNode) -> bool {
431432
if let Some(ref data) = self.data {
432-
data.current.borrow_mut().node_to_node_index.contains_key(dep_node)
433+
data.current.borrow_mut().data.contains_key(dep_node)
433434
} else {
434435
false
435436
}
@@ -438,7 +439,7 @@ impl DepGraph {
438439
#[inline]
439440
pub fn fingerprint_of(&self, dep_node_index: DepNodeIndex) -> Fingerprint {
440441
let current = self.data.as_ref().expect("dep graph enabled").current.borrow_mut();
441-
current.data[dep_node_index].fingerprint
442+
current.data.get_index(dep_node_index.index()).unwrap().1.fingerprint
442443
}
443444

444445
pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
@@ -505,25 +506,25 @@ impl DepGraph {
505506
let current_dep_graph = self.data.as_ref().unwrap().current.borrow();
506507

507508
let fingerprints: IndexVec<SerializedDepNodeIndex, _> =
508-
current_dep_graph.data.iter().map(|d| d.fingerprint).collect();
509+
current_dep_graph.data.values().map(|d| d.fingerprint).collect();
509510
let nodes: IndexVec<SerializedDepNodeIndex, _> =
510-
current_dep_graph.data.iter().map(|d| d.node).collect();
511+
current_dep_graph.data.values().map(|d| d.node).collect();
511512

512-
let total_edge_count: usize = current_dep_graph.data.iter()
513+
let total_edge_count: usize = current_dep_graph.data.values()
513514
.map(|d| d.edges.len())
514515
.sum();
515516

516517
let mut edge_list_indices = IndexVec::with_capacity(nodes.len());
517518
let mut edge_list_data = Vec::with_capacity(total_edge_count);
518519

519-
for (current_dep_node_index, edges) in current_dep_graph.data.iter_enumerated()
520+
for (current_dep_node_index, edges) in current_dep_graph.data.values().enumerate()
520521
.map(|(i, d)| (i, &d.edges)) {
521522
let start = edge_list_data.len() as u32;
522523
// This should really just be a memcpy :/
523524
edge_list_data.extend(edges.iter().map(|i| SerializedDepNodeIndex::new(i.index())));
524525
let end = edge_list_data.len() as u32;
525526

526-
debug_assert_eq!(current_dep_node_index.index(), edge_list_indices.len());
527+
debug_assert_eq!(current_dep_node_index, edge_list_indices.len());
527528
edge_list_indices.push((start, end));
528529
}
529530

@@ -613,7 +614,7 @@ impl DepGraph {
613614

614615
#[cfg(not(parallel_compiler))]
615616
{
616-
debug_assert!(!data.current.borrow().node_to_node_index.contains_key(dep_node));
617+
debug_assert!(!data.current.borrow().data.contains_key(dep_node));
617618
debug_assert!(data.colors.get(prev_dep_node_index).is_none());
618619
}
619620

@@ -877,7 +878,8 @@ impl DepGraph {
877878

878879
pub fn mark_loaded_from_cache(&self, dep_node_index: DepNodeIndex, state: bool) {
879880
debug!("mark_loaded_from_cache({:?}, {})",
880-
self.data.as_ref().unwrap().current.borrow().data[dep_node_index].node,
881+
self.data.as_ref().unwrap().current.borrow()
882+
.data.get_index(dep_node_index.as_usize()).unwrap().0,
881883
state);
882884

883885
self.data
@@ -890,7 +892,8 @@ impl DepGraph {
890892

891893
pub fn was_loaded_from_cache(&self, dep_node: &DepNode) -> Option<bool> {
892894
let data = self.data.as_ref().unwrap();
893-
let dep_node_index = data.current.borrow().node_to_node_index[dep_node];
895+
let (dep_node_index, _, _) = data.current.borrow().data.get_full(dep_node).unwrap();
896+
let dep_node_index = DepNodeIndex::from_usize(dep_node_index);
894897
data.loaded_from_cache.borrow().get(&dep_node_index).cloned()
895898
}
896899
}
@@ -948,8 +951,7 @@ struct DepNodeData {
948951
}
949952

950953
pub(super) struct CurrentDepGraph {
951-
data: IndexVec<DepNodeIndex, DepNodeData>,
952-
node_to_node_index: FxHashMap<DepNode, DepNodeIndex>,
954+
data: FxIndexMap<DepNode, DepNodeData>,
953955
#[allow(dead_code)]
954956
forbidden_edge: Option<EdgeFilter>,
955957

@@ -1001,11 +1003,7 @@ impl CurrentDepGraph {
10011003
let new_node_count_estimate = (prev_graph_node_count * 102) / 100 + 200;
10021004

10031005
CurrentDepGraph {
1004-
data: IndexVec::with_capacity(new_node_count_estimate),
1005-
node_to_node_index: FxHashMap::with_capacity_and_hasher(
1006-
new_node_count_estimate,
1007-
Default::default(),
1008-
),
1006+
data: FxIndexMap::with_capacity_and_hasher(new_node_count_estimate, Default::default()),
10091007
anon_id_seed: stable_hasher.finish(),
10101008
forbidden_edge,
10111009
total_read_count: 0,
@@ -1052,7 +1050,7 @@ impl CurrentDepGraph {
10521050
edges: SmallVec<[DepNodeIndex; 8]>,
10531051
fingerprint: Fingerprint
10541052
) -> DepNodeIndex {
1055-
debug_assert!(!self.node_to_node_index.contains_key(&dep_node));
1053+
debug_assert!(!self.data.contains_key(&dep_node));
10561054
self.intern_node(dep_node, edges, fingerprint)
10571055
}
10581056

@@ -1062,18 +1060,15 @@ impl CurrentDepGraph {
10621060
edges: SmallVec<[DepNodeIndex; 8]>,
10631061
fingerprint: Fingerprint
10641062
) -> DepNodeIndex {
1065-
debug_assert_eq!(self.node_to_node_index.len(), self.data.len());
1066-
1067-
match self.node_to_node_index.entry(dep_node) {
1068-
Entry::Occupied(entry) => *entry.get(),
1063+
match self.data.entry(dep_node) {
1064+
Entry::Occupied(entry) => DepNodeIndex::from_usize(entry.index()),
10691065
Entry::Vacant(entry) => {
1070-
let dep_node_index = DepNodeIndex::new(self.data.len());
1071-
self.data.push(DepNodeData {
1066+
let dep_node_index = DepNodeIndex::from_usize(entry.index());
1067+
entry.insert(DepNodeData {
10721068
node: dep_node,
10731069
edges,
10741070
fingerprint
10751071
});
1076-
entry.insert(dep_node_index);
10771072
dep_node_index
10781073
}
10791074
}

0 commit comments

Comments
 (0)