]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove ld/st-followed nil checks for PPC64
authorDavid Chase <drchase@google.com>
Tue, 6 Sep 2016 16:05:02 +0000 (09:05 -0700)
committerDavid Chase <drchase@google.com>
Tue, 6 Sep 2016 18:52:13 +0000 (18:52 +0000)
Enabled checks (except for DUFF-ops which aren't implemented yet).
Added ppc64le to relevant test.

Also updated register list to reflect no-longer-reserved-
for-constants status (file was missed in that change).

Updates #16010.

Change-Id: I31b1aac19e14994f760f2ecd02edbeb1f78362e7
Reviewed-on: https://go-review.googlesource.com/28548
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/ppc64/ssa.go
test/nilptr3_ssa.go

index 802105cf6bd3698c0c4c6fe8bb40606ae4455fb1..4019e621360219a2d7ef620d31ab749f31211625 100644 (file)
@@ -73,11 +73,11 @@ var ssaRegToReg = []int16{
        ppc64.REG_F24,
        ppc64.REG_F25,
        ppc64.REG_F26,
-       // ppc64.REG_F27, // reserved for "floating conversion constant"
-       // ppc64.REG_F28, // 0.0
-       // ppc64.REG_F29, // 0.5
-       // ppc64.REG_F30, // 1.0
-       // ppc64.REG_F31, // 2.0
+       ppc64.REG_F27,
+       ppc64.REG_F28,
+       ppc64.REG_F29,
+       ppc64.REG_F30,
+       ppc64.REG_F31,
 
        // ppc64.REG_CR0,
        // ppc64.REG_CR1,
@@ -94,6 +94,10 @@ var ssaRegToReg = []int16{
        // ppc64.REG_CTR,
 }
 
+// Smallest possible faulting page at address zero,
+// see ../../../../runtime/mheap.go:/minPhysPageSize
+const minZeroPage = 4096
+
 var condOps = map[ssa.Op]obj.As{
        ssa.OpPPC64Equal:        ppc64.ABEQ,
        ssa.OpPPC64NotEqual:     ppc64.ABNE,
@@ -848,61 +852,62 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        case ssa.OpPPC64LoweredNilCheck:
                // Optimization - if the subsequent block has a load or store
                // at the same address, we don't need to issue this instruction.
-               // mem := v.Args[1]
-               // for _, w := range v.Block.Succs[0].Block().Values {
-               //      if w.Op == ssa.OpPhi {
-               //              if w.Type.IsMemory() {
-               //                      mem = w
-               //              }
-               //              continue
-               //      }
-               //      if len(w.Args) == 0 || !w.Args[len(w.Args)-1].Type.IsMemory() {
-               //              // w doesn't use a store - can't be a memory op.
-               //              continue
-               //      }
-               //      if w.Args[len(w.Args)-1] != mem {
-               //              v.Fatalf("wrong store after nilcheck v=%s w=%s", v, w)
-               //      }
-               //      switch w.Op {
-               //      case ssa.OpPPC64MOVBload, ssa.OpPPC64MOVBUload, ssa.OpPPC64MOVHload, ssa.OpPPC64MOVHUload,
-               //              ssa.OpPPC64MOVWload, ssa.OpPPC64MOVFload, ssa.OpPPC64MOVDload,
-               //              ssa.OpPPC64MOVBstore, ssa.OpPPC64MOVHstore, ssa.OpPPC64MOVWstore,
-               //              ssa.OpPPC64MOVFstore, ssa.OpPPC64MOVDstore:
-               //              // arg0 is ptr, auxint is offset
-               //              if w.Args[0] == v.Args[0] && w.Aux == nil && w.AuxInt >= 0 && w.AuxInt < minZeroPage {
-               //                      if gc.Debug_checknil != 0 && int(v.Line) > 1 {
-               //                              gc.Warnl(v.Line, "removed nil check")
-               //                      }
-               //                      return
-               //              }
-               //      case ssa.OpPPC64DUFFZERO, ssa.OpPPC64LoweredZero, ssa.OpPPC64LoweredZeroU:
-               //              // arg0 is ptr
-               //              if w.Args[0] == v.Args[0] {
-               //                      if gc.Debug_checknil != 0 && int(v.Line) > 1 {
-               //                              gc.Warnl(v.Line, "removed nil check")
-               //                      }
-               //                      return
-               //              }
-               //      case ssa.OpPPC64DUFFCOPY, ssa.OpPPC64LoweredMove, ssa.OpPPC64LoweredMoveU:
-               //              // arg0 is dst ptr, arg1 is src ptr
-               //              if w.Args[0] == v.Args[0] || w.Args[1] == v.Args[0] {
-               //                      if gc.Debug_checknil != 0 && int(v.Line) > 1 {
-               //                              gc.Warnl(v.Line, "removed nil check")
-               //                      }
-               //                      return
-               //              }
-               //      default:
-               //      }
-               //      if w.Type.IsMemory() {
-               //              if w.Op == ssa.OpVarDef || w.Op == ssa.OpVarKill || w.Op == ssa.OpVarLive {
-               //                      // these ops are OK
-               //                      mem = w
-               //                      continue
-               //              }
-               //              // We can't delay the nil check past the next store.
-               //              break
-               //      }
-               // }
+               mem := v.Args[1]
+               for _, w := range v.Block.Succs[0].Block().Values {
+                       if w.Op == ssa.OpPhi {
+                               if w.Type.IsMemory() {
+                                       mem = w
+                               }
+                               continue
+                       }
+                       if len(w.Args) == 0 || !w.Args[len(w.Args)-1].Type.IsMemory() {
+                               // w doesn't use a store - can't be a memory op.
+                               continue
+                       }
+                       if w.Args[len(w.Args)-1] != mem {
+                               v.Fatalf("wrong store after nilcheck v=%s w=%s", v, w)
+                       }
+                       switch w.Op {
+                       case ssa.OpPPC64MOVBload, ssa.OpPPC64MOVBZload, ssa.OpPPC64MOVHload, ssa.OpPPC64MOVHZload,
+                               ssa.OpPPC64MOVWload, ssa.OpPPC64MOVWZload, ssa.OpPPC64MOVDload, ssa.OpPPC64FMOVDload, ssa.OpPPC64FMOVSload,
+                               ssa.OpPPC64MOVBstore, ssa.OpPPC64MOVHstore, ssa.OpPPC64MOVWstore,
+                               ssa.OpPPC64MOVDstore, ssa.OpPPC64FMOVSstore, ssa.OpPPC64FMOVDstore,
+                               ssa.OpPPC64MOVDstorezero, ssa.OpPPC64MOVWstorezero, ssa.OpPPC64MOVHstorezero, ssa.OpPPC64MOVBstorezero:
+                               // arg0 is ptr, auxint is offset
+                               if w.Args[0] == v.Args[0] && w.Aux == nil && w.AuxInt >= 0 && w.AuxInt < minZeroPage {
+                                       if gc.Debug_checknil != 0 && int(v.Line) > 1 {
+                                               gc.Warnl(v.Line, "removed nil check")
+                                       }
+                                       return
+                               }
+                       case ssa.OpPPC64LoweredZero: // ssa.OpPPC64DUFFZERO,
+                               // arg0 is ptr
+                               if w.Args[0] == v.Args[0] {
+                                       if gc.Debug_checknil != 0 && int(v.Line) > 1 {
+                                               gc.Warnl(v.Line, "removed nil check")
+                                       }
+                                       return
+                               }
+                       case ssa.OpPPC64LoweredMove: // ssa.OpPPC64DUFFCOPY,
+                               // arg0 is dst ptr, arg1 is src ptr
+                               if w.Args[0] == v.Args[0] || w.Args[1] == v.Args[0] {
+                                       if gc.Debug_checknil != 0 && int(v.Line) > 1 {
+                                               gc.Warnl(v.Line, "removed nil check")
+                                       }
+                                       return
+                               }
+                       default:
+                       }
+                       if w.Type.IsMemory() {
+                               if w.Op == ssa.OpVarDef || w.Op == ssa.OpVarKill || w.Op == ssa.OpVarLive {
+                                       // these ops are OK
+                                       mem = w
+                                       continue
+                               }
+                               // We can't delay the nil check past the next store.
+                               break
+                       }
+               }
                // Issue a load which will fault if arg is nil.
                p := gc.Prog(ppc64.AMOVB)
                p.From.Type = obj.TYPE_MEM
index 38c511997ce78f7dff385918902864aacfd4c16d..9fb533d0f9f9b3b178ad87fbab3f9f3f9dd192d5 100644 (file)
@@ -1,5 +1,5 @@
 // errorcheck -0 -d=nil
-// +build amd64 arm amd64p32 386 arm64 mips64 mips64le
+// +build amd64 arm amd64p32 386 arm64 mips64 mips64le ppc64le
 
 // Copyright 2013 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style