Skip to content

Commit 338f939

Browse files
committed
Auto merge of rust-lang#78607 - HeroicKatora:post-order-walk-iter, r=davidtwco
Transform post order walk to an iterative approach The previous recursive approach might overflow the stack when walking a particularly deep, list-like, graph. In particular, dominator calculation for borrow checking does such a traversal and very long functions might lead to a region dependency graph with in this problematic structure. This addresses what appears to be the cause of rust-lang#78567 (`@SunHao-0` thanks for the stack trace).
2 parents 499ebcf + af72a70 commit 338f939

File tree

1 file changed

+20
-5
lines changed
  • compiler/rustc_data_structures/src/graph/iterate

1 file changed

+20
-5
lines changed

compiler/rustc_data_structures/src/graph/iterate/mod.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,31 @@ fn post_order_walk<G: DirectedGraph + WithSuccessors + WithNumNodes>(
3333
result: &mut Vec<G::Node>,
3434
visited: &mut IndexVec<G::Node, bool>,
3535
) {
36+
struct PostOrderFrame<Node, Iter> {
37+
node: Node,
38+
iter: Iter,
39+
}
40+
3641
if visited[node] {
3742
return;
3843
}
39-
visited[node] = true;
4044

41-
for successor in graph.successors(node) {
42-
post_order_walk(graph, successor, result, visited);
43-
}
45+
let mut stack = vec![PostOrderFrame { node, iter: graph.successors(node) }];
46+
47+
'recurse: while let Some(frame) = stack.last_mut() {
48+
let node = frame.node;
49+
visited[node] = true;
4450

45-
result.push(node);
51+
while let Some(successor) = frame.iter.next() {
52+
if !visited[successor] {
53+
stack.push(PostOrderFrame { node: successor, iter: graph.successors(successor) });
54+
continue 'recurse;
55+
}
56+
}
57+
58+
let _ = stack.pop();
59+
result.push(node);
60+
}
4661
}
4762

4863
pub fn reverse_post_order<G: DirectedGraph + WithSuccessors + WithNumNodes>(

0 commit comments

Comments
 (0)