diff options
| author | Mark Rousskov <mark.simulacrum@gmail.com> | 2022-02-23 10:31:26 -0500 |
|---|---|---|
| committer | Mark Rousskov <mark.simulacrum@gmail.com> | 2022-02-23 16:07:56 -0500 |
| commit | 4d89292785653e399512d85f95a9870836ec9632 (patch) | |
| tree | 89dc0f6631b027fd47d71b31332aac521d237a43 /compiler/rustc_data_structures/src/graph | |
| parent | c651ba8a542c7d89b271efbf024a31091c824f4b (diff) | |
| download | rust-4d89292785653e399512d85f95a9870836ec9632.tar.gz rust-4d89292785653e399512d85f95a9870836ec9632.zip | |
Avoid exhausting stack space in dominator compression
Diffstat (limited to 'compiler/rustc_data_structures/src/graph')
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/dominators/mod.rs | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index 0d2ae115cb0..00913a483db 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs @@ -241,9 +241,19 @@ fn compress( v: PreorderIndex, ) { assert!(is_processed(v, lastlinked)); - let u = ancestor[v]; - if is_processed(u, lastlinked) { - compress(ancestor, lastlinked, semi, label, u); + // Compute the processed list of ancestors + // + // We use a heap stack here to avoid recursing too deeply, exhausting the + // stack space. + let mut stack: smallvec::SmallVec<[_; 8]> = smallvec::smallvec![v]; + let mut u = ancestor[v]; + while is_processed(u, lastlinked) { + stack.push(u); + u = ancestor[u]; + } + + // Then in reverse order, popping the stack + for &[v, u] in stack.array_windows().rev() { if semi[label[u]] < semi[label[v]] { label[v] = label[u]; } |
