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:
parent
b7041c7ad1
commit
15728ce950
@ -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)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user