rustc_middle/dep_graph/
retained.rs1use rustc_data_structures::fx::FxHashMap;
2use rustc_data_structures::graph::linked_graph::{Direction, INCOMING, LinkedGraph, NodeIndex};
3use rustc_index::IndexVec;
4
5use super::{DepNode, DepNodeIndex};
6
7pub struct RetainedDepGraph {
14 pub inner: LinkedGraph<DepNode, ()>,
15 pub indices: FxHashMap<DepNode, NodeIndex>,
16 pub dep_index_to_index: IndexVec<DepNodeIndex, Option<NodeIndex>>,
17}
18
19impl RetainedDepGraph {
20 pub fn new(prev_node_count: usize) -> Self {
21 let node_count = prev_node_count + prev_node_count / 4;
22 let edge_count = 6 * node_count;
23
24 let inner = LinkedGraph::with_capacity(node_count, edge_count);
25 let indices = FxHashMap::default();
26 let dep_index_to_index = IndexVec::new();
27
28 Self { inner, indices, dep_index_to_index }
29 }
30
31 pub fn push(&mut self, index: DepNodeIndex, node: DepNode, edges: &[DepNodeIndex]) {
32 let source = self.inner.add_node(node);
33 self.dep_index_to_index.insert(index, source);
34 self.indices.insert(node, source);
35
36 for &target in edges.iter() {
37 if let Some(&Some(target)) = self.dep_index_to_index.get(target) {
40 self.inner.add_edge(source, target, ());
41 }
42 }
43 }
44
45 pub fn nodes(&self) -> Vec<&DepNode> {
46 self.inner.all_nodes().iter().map(|n| &n.data).collect()
47 }
48
49 pub fn edges(&self) -> Vec<(&DepNode, &DepNode)> {
50 self.inner
51 .all_edges()
52 .iter()
53 .map(|edge| (edge.source(), edge.target()))
54 .map(|(s, t)| (self.inner.node_data(s), self.inner.node_data(t)))
55 .collect()
56 }
57
58 fn reachable_nodes(&self, node: &DepNode, direction: Direction) -> Vec<&DepNode> {
59 if let Some(&index) = self.indices.get(node) {
60 self.inner.depth_traverse(index, direction).map(|s| self.inner.node_data(s)).collect()
61 } else {
62 ::alloc::vec::Vec::new()vec![]
63 }
64 }
65
66 pub fn transitive_predecessors(&self, node: &DepNode) -> Vec<&DepNode> {
68 self.reachable_nodes(node, INCOMING)
69 }
70}