1
0
mirror of https://github.com/golang/go synced 2024-11-17 06:54:48 -07:00

cmd/compile: disable rewrite loop detector for deadcode-only changes

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>
This commit is contained in:
Keith Randall 2022-03-14 15:17:43 -07:00
parent b7041c7ad1
commit 15728ce950

View File

@ -40,6 +40,7 @@ func applyRewrite(f *Func, rb blockRewriter, rv valueRewriter, deadcode deadValu
var states map[string]bool var states map[string]bool
for { for {
change := false change := false
deadChange := false
for _, b := range f.Blocks { for _, b := range f.Blocks {
var b0 *Block var b0 *Block
if debug > 1 { 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. // Not quite a deadcode pass, because it does not handle cycles.
// But it should help Uses==1 rules to fire. // But it should help Uses==1 rules to fire.
v.reset(OpInvalid) v.reset(OpInvalid)
change = true deadChange = true
} }
// No point rewriting values which aren't used. // No point rewriting values which aren't used.
continue continue
@ -145,15 +146,16 @@ func applyRewrite(f *Func, rb blockRewriter, rv valueRewriter, deadcode deadValu
} }
} }
} }
if !change { if !change && !deadChange {
break break
} }
iters++ 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). // 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 // As of Sep 2021, 90% of rewrites complete in 4 iterations or fewer
// and the maximum value encountered during make.bash is 12. // and the maximum value encountered during make.bash is 12.
// Start checking for cycles. (This is too expensive to do routinely.) // 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 { if states == nil {
states = make(map[string]bool) states = make(map[string]bool)
} }