]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: disable rewrite loop detector for deadcode-only changes
authorKeith Randall <khr@golang.org>
Mon, 14 Mar 2022 22:17:43 +0000 (15:17 -0700)
committerKeith Randall <khr@golang.org>
Tue, 15 Mar 2022 00:05:18 +0000 (00:05 +0000)
We're guaranteed we won't infinite loop on deadcode-only changes,
because each change converts valid -> invalid, and there are only a
finite number of valid values.

The loops this test is looking for are those generated by rule
applications, so it isn't useful to check for loops when rules aren't
involved.

Fixes #51639

Change-Id: Idf1abeab9d47baafddc3a1197d5064faaf07ef78
Reviewed-on: https://go-review.googlesource.com/c/go/+/392760
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Trust: Josh Bleecher Snyder <josharian@gmail.com>

src/cmd/compile/internal/ssa/rewrite.go

index 9136c59e65494f8ee56341965a652f04bd1466ab..eb8fa0c02abe44f56be68f352d7ffe32a7f1e70f 100644 (file)
@@ -40,6 +40,7 @@ func applyRewrite(f *Func, rb blockRewriter, rv valueRewriter, deadcode deadValu
        var states map[string]bool
        for {
                change := false
+               deadChange := false
                for _, b := range f.Blocks {
                        var b0 *Block
                        if debug > 1 {
@@ -73,7 +74,7 @@ func applyRewrite(f *Func, rb blockRewriter, rv valueRewriter, deadcode deadValu
                                                // Not quite a deadcode pass, because it does not handle cycles.
                                                // But it should help Uses==1 rules to fire.
                                                v.reset(OpInvalid)
-                                               change = true
+                                               deadChange = true
                                        }
                                        // No point rewriting values which aren't used.
                                        continue
@@ -145,15 +146,16 @@ func applyRewrite(f *Func, rb blockRewriter, rv valueRewriter, deadcode deadValu
                                }
                        }
                }
-               if !change {
+               if !change && !deadChange {
                        break
                }
                iters++
-               if iters > 1000 || debug >= 2 {
+               if (iters > 1000 || debug >= 2) && change {
                        // We've done a suspiciously large number of rewrites (or we're in debug mode).
                        // As of Sep 2021, 90% of rewrites complete in 4 iterations or fewer
                        // and the maximum value encountered during make.bash is 12.
                        // Start checking for cycles. (This is too expensive to do routinely.)
+                       // Note: we avoid this path for deadChange-only iterations, to fix #51639.
                        if states == nil {
                                states = make(map[string]bool)
                        }