]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile/ssa: don't perform nilcheck on OpAddr/OpAddPtr values
authorTodd Neal <todd@tneal.org>
Mon, 3 Aug 2015 23:08:22 +0000 (18:08 -0500)
committerTodd Neal <todd@tneal.org>
Thu, 6 Aug 2015 23:11:34 +0000 (23:11 +0000)
Don't nilcheck values that were constructed as a result of OpAddr or
OpAddPtr.

Change-Id: I38053e905d1b76a2a64e77f84e444d38a5217108
Reviewed-on: https://go-review.googlesource.com/13256
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/nilcheck.go
src/cmd/compile/internal/ssa/nilcheck_test.go

index b9964b29803fdecf88883cd22cd95d52c028c045..ac7af5c60d3ace166a7d20205f8e9fa78b194423 100644 (file)
@@ -53,6 +53,19 @@ func nilcheckelim(f *Func) {
                var pushRecPtr bool
                switch node.op {
                case Work:
+                       // 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 node.block.Values {
+                               if v.Op == OpAddr || v.Op == OpAddPtr {
+                                       // set this immediately instead of
+                                       // using SetPtr so we can potentially
+                                       // remove an OpIsNonNil check in the
+                                       // current work block
+                                       nonNilValues[v.ID] = true
+                               }
+                       }
+
                        if node.ptr != nil {
                                // already have a nilcheck in the dominator path
                                if nonNilValues[node.ptr.ID] {
index 0ebf2bc801ccc4189a4b0aaec7b7900f2f428a52..e542df25c4eea17d9eedcc8425876010bf54fce0 100644 (file)
@@ -134,9 +134,8 @@ func TestNilcheckDomOrder(t *testing.T) {
        }
 }
 
-//TODO: Disabled until we track OpAddr constructed values
 // TestNilcheckAddr verifies that nilchecks of OpAddr constructed values are removed.
-func DISABLETestNilcheckAddr(t *testing.T) {
+func TestNilcheckAddr(t *testing.T) {
        ptrType := &TypeImpl{Size_: 8, Ptr: true, Name: "testptr"} // dummy for testing
        c := NewConfig("amd64", DummyFrontend{t})
        fun := Fun(c, "entry",
@@ -168,6 +167,39 @@ func DISABLETestNilcheckAddr(t *testing.T) {
        }
 }
 
+// TestNilcheckAddPtr verifies that nilchecks of OpAddPtr constructed values are removed.
+func TestNilcheckAddPtr(t *testing.T) {
+       ptrType := &TypeImpl{Size_: 8, Ptr: true, Name: "testptr"} // dummy for testing
+       c := NewConfig("amd64", DummyFrontend{t})
+       fun := Fun(c, "entry",
+               Bloc("entry",
+                       Valu("mem", OpArg, TypeMem, 0, ".mem"),
+                       Valu("sb", OpSB, TypeInvalid, 0, nil),
+                       Goto("checkPtr")),
+               Bloc("checkPtr",
+                       Valu("ptr1", OpAddPtr, ptrType, 0, nil, "sb"),
+                       Valu("bool1", OpIsNonNil, TypeBool, 0, nil, "ptr1"),
+                       If("bool1", "extra", "exit")),
+               Bloc("extra",
+                       Goto("exit")),
+               Bloc("exit",
+                       Exit("mem")))
+
+       CheckFunc(fun.f)
+       nilcheckelim(fun.f)
+
+       // clean up the removed nil check
+       fuse(fun.f)
+       deadcode(fun.f)
+
+       CheckFunc(fun.f)
+       for _, b := range fun.f.Blocks {
+               if b == fun.blocks["checkPtr"] && isNilCheck(b) {
+                       t.Errorf("checkPtr was not eliminated")
+               }
+       }
+}
+
 // TestNilcheckKeepRemove verifies that dupliate checks of the same pointer
 // are removed, but checks of different pointers are not.
 func TestNilcheckKeepRemove(t *testing.T) {