]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: eliminate more nil checks of phis
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 9 Mar 2017 21:30:20 +0000 (13:30 -0800)
committerDavid Chase <drchase@google.com>
Mon, 13 Mar 2017 18:38:28 +0000 (18:38 +0000)
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>
src/cmd/compile/internal/ssa/nilcheck.go

index ea6523d24c47ba207f2c8a39bfb345e56a04cb99..c63b7d2200ba79ea0a5ccf79c9629843c183d538 100644 (file)
@@ -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
                                }
                        }
                }