aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josharian@gmail.com>2017-03-09 13:30:20 -0800
committerDavid Chase <drchase@google.com>2017-03-13 18:38:28 +0000
commitc694f6f3a80bcb42960e021b279eb6d23baf2c50 (patch)
tree07cdf32814ddc1f978a5cf49afc6dcfd4f58489a /src
parent4e0c7c3f61475116c4ae8d11ef796819d9c404f0 (diff)
downloadgo-c694f6f3a80bcb42960e021b279eb6d23baf2c50.tar.xz
cmd/compile: eliminate more nil checks of phis
The existing implementation started by eliminating nil checks for OpAddr, OpAddPtr, and OpPhis with all non-nil args. However, some OpPhis had all non-nil args, but their args had not been processed yet. Pull the OpPhi checks into their own loop, and repeat until stabilization. Eliminates a dozen additional nilchecks during make.bash. Negligible compiler performance impact. Change-Id: If7b803c3ad7582af7d9867d05ca13e03e109d864 Reviewed-on: https://go-review.googlesource.com/37999 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/ssa/nilcheck.go35
1 files changed, 24 insertions, 11 deletions
diff --git a/src/cmd/compile/internal/ssa/nilcheck.go b/src/cmd/compile/internal/ssa/nilcheck.go
index ea6523d24c..c63b7d2200 100644
--- a/src/cmd/compile/internal/ssa/nilcheck.go
+++ b/src/cmd/compile/internal/ssa/nilcheck.go
@@ -39,23 +39,36 @@ func nilcheckelim(f *Func) {
// make an initial pass identifying any non-nil values
for _, b := range f.Blocks {
- // a value resulting from taking the address of a
- // value, or a value constructed from an offset of a
- // non-nil ptr (OpAddPtr) implies it is non-nil
for _, v := range b.Values {
+ // a value resulting from taking the address of a
+ // value, or a value constructed from an offset of a
+ // non-nil ptr (OpAddPtr) implies it is non-nil
if v.Op == OpAddr || v.Op == OpAddPtr {
nonNilValues[v.ID] = true
- } else if v.Op == OpPhi {
+ }
+ }
+ }
+
+ for changed := true; changed; {
+ changed = false
+ for _, b := range f.Blocks {
+ for _, v := range b.Values {
// phis whose arguments are all non-nil
// are non-nil
- argsNonNil := true
- for _, a := range v.Args {
- if !nonNilValues[a.ID] {
- argsNonNil = false
+ if v.Op == OpPhi {
+ argsNonNil := true
+ for _, a := range v.Args {
+ if !nonNilValues[a.ID] {
+ argsNonNil = false
+ break
+ }
+ }
+ if argsNonNil {
+ if !nonNilValues[v.ID] {
+ changed = true
+ }
+ nonNilValues[v.ID] = true
}
- }
- if argsNonNil {
- nonNilValues[v.ID] = true
}
}
}