Skip to content

Commit

Permalink
Auto merge of #78607 - HeroicKatora:post-order-walk-iter, r=davidtwco
Browse files Browse the repository at this point in the history
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 #78567 (`@SunHao-0` thanks for the stack trace).
  • Loading branch information
bors committed Nov 2, 2020
2 parents 499ebcf + af72a70 commit 338f939
Showing 1 changed file with 20 additions and 5 deletions.
25 changes: 20 additions & 5 deletions compiler/rustc_data_structures/src/graph/iterate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,31 @@ fn post_order_walk<G: DirectedGraph + WithSuccessors + WithNumNodes>(
result: &mut Vec<G::Node>,
visited: &mut IndexVec<G::Node, bool>,
) {
struct PostOrderFrame<Node, Iter> {
node: Node,
iter: Iter,
}

if visited[node] {
return;
}
visited[node] = true;

for successor in graph.successors(node) {
post_order_walk(graph, successor, result, visited);
}
let mut stack = vec![PostOrderFrame { node, iter: graph.successors(node) }];

'recurse: while let Some(frame) = stack.last_mut() {
let node = frame.node;
visited[node] = true;

result.push(node);
while let Some(successor) = frame.iter.next() {
if !visited[successor] {
stack.push(PostOrderFrame { node: successor, iter: graph.successors(successor) });
continue 'recurse;
}
}

let _ = stack.pop();
result.push(node);
}
}

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

0 comments on commit 338f939

Please sign in to comment.