diff options
| author | bors <bors@rust-lang.org> | 2020-11-02 16:01:10 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-11-02 16:01:10 +0000 |
| commit | 338f939a8d77061896cd0a1ca87a2c6d1f4ec359 (patch) | |
| tree | c026b97b77eae76c1b6a472f305907f908f802e2 | |
| parent | 499ebcfdf3b09a646154f321b7c28f5105e4dbf7 (diff) | |
| parent | af72a70ee27faa85522f7656e042c85ab1ee275e (diff) | |
| download | rust-338f939a8d77061896cd0a1ca87a2c6d1f4ec359.tar.gz rust-338f939a8d77061896cd0a1ca87a2c6d1f4ec359.zip | |
Auto merge of #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 #78567 (`@SunHao-0` thanks for the stack trace).
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/iterate/mod.rs | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index 5f42d46e285..1634c586316 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs @@ -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>( |
