diff options
| author | Andreas Molzer <andreas.molzer@gmx.de> | 2020-10-31 17:56:13 +0100 |
|---|---|---|
| committer | Andreas Molzer <andreas.molzer@gmx.de> | 2020-10-31 18:52:00 +0100 |
| commit | af72a70ee27faa85522f7656e042c85ab1ee275e (patch) | |
| tree | 51bcfa310359132c94a5ab34f669d0c85a96cee7 /compiler/rustc_data_structures/src/graph/iterate/mod.rs | |
| parent | ffe52882ed79be67344dd6085559e308241e7f60 (diff) | |
| download | rust-af72a70ee27faa85522f7656e042c85ab1ee275e.tar.gz rust-af72a70ee27faa85522f7656e042c85ab1ee275e.zip | |
Move post order walk to 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.
Diffstat (limited to 'compiler/rustc_data_structures/src/graph/iterate/mod.rs')
| -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>( |
