]> git.lizzy.rs Git - rust.git/commitdiff
Avoid exhausting stack space in dominator compression
authorMark Rousskov <mark.simulacrum@gmail.com>
Wed, 23 Feb 2022 15:31:26 +0000 (10:31 -0500)
committerMark Rousskov <mark.simulacrum@gmail.com>
Wed, 23 Feb 2022 21:07:56 +0000 (16:07 -0500)
compiler/rustc_data_structures/src/graph/dominators/mod.rs

index 0d2ae115cb0d29d3bf561f22f35e9314fc3a440d..00913a483db0efe6bc39aeb1743f30ee2351181b 100644 (file)
@@ -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];
         }