Skip to content

Commit 7abab8a

Browse files
committed
add a comment about optimality that somehow got removed
1 parent afbf6c8 commit 7abab8a

File tree

2 files changed

+76
-58
lines changed

2 files changed

+76
-58
lines changed

src/librustc_incremental/persist/preds/compress/construct.rs

+12
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@ pub(super) fn construct_graph<'g, N, I, O>(r: &mut GraphReduce<'g, N, I, O>, dag
7878
//
7979
// Now if we were to remove Y, we would have a total of 8 edges: both WP0 and WP1
8080
// depend on INPUT0...INPUT3. As it is, we have 6 edges.
81+
//
82+
// NB: The current rules are not optimal. For example, given this
83+
// input graph:
84+
//
85+
// OUT0 -rf-> X
86+
// OUT1 -rf-> X
87+
// X -rf -> INPUT0
88+
//
89+
// we will preserve X because it has two "consumers" (OUT0 and
90+
// OUT1). We could as easily skip it, but we'd have to tally up
91+
// the number of input nodes that it (transitively) reaches, and I
92+
// was too lazy to do so. This is the unit test `suboptimal`.
8193

8294
let mut retain_map = FxHashMap();
8395
let mut new_graph = Graph::new();

src/librustc_incremental/persist/preds/compress/test.rs

+64-58
Original file line numberDiff line numberDiff line change
@@ -151,62 +151,69 @@ fn test3() {
151151
]);
152152
}
153153

154-
//#[test]
155-
//fn test_cached_dfs_cyclic() {
156-
//
157-
// // 0 1 <---- 2 3
158-
// // ^ | ^ ^
159-
// // | v | |
160-
// // 4 ----> 5 ----> 6 ----> 7
161-
// // ^ ^ ^ ^
162-
// // | | | |
163-
// // 8 9 10 11
164-
//
165-
//
166-
// let mut g: Graph<bool, ()> = Graph::new();
167-
// g.add_node(false);
168-
// g.add_node(false);
169-
// g.add_node(false);
170-
// g.add_node(false);
171-
// g.add_node(false);
172-
// g.add_node(false);
173-
// g.add_node(false);
174-
// g.add_node(false);
175-
// g.add_node(true);
176-
// g.add_node(true);
177-
// g.add_node(true);
178-
// g.add_node(true);
179-
//
180-
// g.add_edge(NodeIndex( 4), NodeIndex(0), ());
181-
// g.add_edge(NodeIndex( 8), NodeIndex(4), ());
182-
// g.add_edge(NodeIndex( 4), NodeIndex(5), ());
183-
// g.add_edge(NodeIndex( 1), NodeIndex(5), ());
184-
// g.add_edge(NodeIndex( 9), NodeIndex(5), ());
185-
// g.add_edge(NodeIndex( 5), NodeIndex(6), ());
186-
// g.add_edge(NodeIndex( 6), NodeIndex(2), ());
187-
// g.add_edge(NodeIndex( 2), NodeIndex(1), ());
188-
// g.add_edge(NodeIndex(10), NodeIndex(6), ());
189-
// g.add_edge(NodeIndex( 6), NodeIndex(7), ());
190-
// g.add_edge(NodeIndex(11), NodeIndex(7), ());
191-
// g.add_edge(NodeIndex( 7), NodeIndex(3), ());
192-
//
193-
// let mut ws1 = DfsWorkspace::new(g.len_nodes());
194-
// let mut ws2 = DfsWorkspace::new(g.len_nodes());
195-
// let mut visit_counts: Vec<_> = g.all_nodes().iter().map(|_| 0u32).collect();
196-
// let mut cache: Vec<Option<Box<[u32]>>> = g.all_nodes().iter().map(|_| None).collect();
197-
//
198-
// fn is_root(x: &bool) -> bool { *x }
199-
//
200-
// for _ in 0 .. CACHING_THRESHOLD + 1 {
201-
// find_roots(&g, 2, &mut visit_counts, &mut cache[..], is_root, &mut ws1, Some(&mut ws2));
202-
// ws1.output.nodes.sort();
203-
// assert_eq!(ws1.output.nodes, vec![8, 9, 10]);
204-
//
205-
// find_roots(&g, 3, &mut visit_counts, &mut cache[..], is_root, &mut ws1, Some(&mut ws2));
206-
// ws1.output.nodes.sort();
207-
// assert_eq!(ws1.output.nodes, vec![8, 9, 10, 11]);
208-
// }
209-
//}
154+
#[test]
155+
fn test_cached_dfs_cyclic() {
156+
157+
// 0 1 <---- 2 3
158+
// ^ | ^ ^
159+
// | v | |
160+
// 4 ----> 5 ----> 6 ----> 7
161+
// ^ ^ ^ ^
162+
// | | | |
163+
// 8 9 10 11
164+
165+
let (graph, _nodes) = graph! {
166+
// edges from above diagram, in columns, top-to-bottom:
167+
n4 -> n0,
168+
n8 -> n4,
169+
n4 -> n5,
170+
n1 -> n5,
171+
n9 -> n5,
172+
n2 -> n1,
173+
n5 -> n6,
174+
n6 -> n2,
175+
n10 -> n6,
176+
n6 -> n7,
177+
n7 -> n3,
178+
n11 -> n7,
179+
};
180+
181+
// 0 1 2 3
182+
// ^ ^ / ^
183+
// | |/ |
184+
// 4 ----> 5 --------------+
185+
// ^ ^ \ |
186+
// | | \ |
187+
// 8 9 10 11
188+
189+
reduce(&graph, &["n8", "n9", "n10", "n11"], &["n0", "n1", "n2", "n3"], &[
190+
"n10 -> n5",
191+
"n11 -> n3",
192+
"n4 -> n0",
193+
"n4 -> n5",
194+
"n5 -> n1",
195+
"n5 -> n2",
196+
"n5 -> n3",
197+
"n8 -> n4",
198+
"n9 -> n5"
199+
]);
200+
}
201+
202+
/// Demonstrates the case where we don't reduce as much as we could.
203+
#[test]
204+
fn suboptimal() {
205+
let (graph, _nodes) = graph! {
206+
INPUT0 -> X,
207+
X -> OUTPUT0,
208+
X -> OUTPUT1,
209+
};
210+
211+
reduce(&graph, &["INPUT0"], &["OUTPUT0", "OUTPUT1"], &[
212+
"INPUT0 -> X",
213+
"X -> OUTPUT0",
214+
"X -> OUTPUT1"
215+
]);
216+
}
210217

211218
#[test]
212219
fn test_cycle_output() {
@@ -229,7 +236,7 @@ fn test_cycle_output() {
229236
D -> C1,
230237
};
231238

232-
// [A] -> [C0] <-> [D]
239+
// [A] -> [C0] --> [D]
233240
// +----> [E]
234241
// ^
235242
// [B] -------------+
@@ -238,6 +245,5 @@ fn test_cycle_output() {
238245
"B -> E",
239246
"C0 -> D",
240247
"C0 -> E",
241-
"D -> C0"
242248
]);
243249
}

0 commit comments

Comments
 (0)