]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove some write barriers for stack writes
authorCherry Zhang <cherryyz@google.com>
Tue, 4 Oct 2016 03:01:26 +0000 (23:01 -0400)
committerCherry Zhang <cherryyz@google.com>
Mon, 10 Oct 2016 13:15:04 +0000 (13:15 +0000)
This, along with CL 30140, removes ~50% of stack write barriers
mentioned in issue #17330. The remaining are most due to Phi and
FwdRef, which is not resolved when building SSA. We might be
able to do it at a later stage where Phi and Copy propagations
are done, but matching an if-(store-store-call)+ sequence seems
not very pleasant.

Updates #17330.

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

index e4eefd22a7a58ced1146d48c800a5d44d8cf5cab..8e9e915fd4a7bf16f9bd0f4c00fb9c81203d2771 100644 (file)
@@ -2161,7 +2161,11 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
                }
                capaddr := s.newValue1I(ssa.OpOffPtr, pt, int64(array_cap), addr)
                s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, capaddr, r[2], s.mem())
-               s.insertWBstore(pt, addr, r[0], n.Lineno, 0)
+               if isStackAddr(addr) {
+                       s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, pt.Size(), addr, r[0], s.mem())
+               } else {
+                       s.insertWBstore(pt, addr, r[0], n.Lineno, 0)
+               }
                // load the value we just stored to avoid having to spill it
                s.vars[&ptrVar] = s.newValue2(ssa.OpLoad, pt, addr, s.mem())
                s.vars[&lenVar] = r[1] // avoid a spill in the fast path
@@ -2359,7 +2363,7 @@ func (s *state) assign(left *Node, right *ssa.Value, wb, deref bool, line int32,
                        s.vars[&memVar] = s.newValue2I(ssa.OpZero, ssa.TypeMem, sizeAlignAuxInt(t), addr, s.mem())
                        return
                }
-               if wb {
+               if wb && !isStackAddr(addr) {
                        s.insertWBmove(t, addr, right, line, rightIsVolatile)
                        return
                }
@@ -2367,7 +2371,7 @@ func (s *state) assign(left *Node, right *ssa.Value, wb, deref bool, line int32,
                return
        }
        // Treat as a store.
-       if wb {
+       if wb && !isStackAddr(addr) {
                if skip&skipPtr != 0 {
                        // Special case: if we don't write back the pointers, don't bother
                        // doing the write barrier check.
@@ -3259,6 +3263,20 @@ func (s *state) rtcall(fn *Node, returns bool, results []*Type, args ...*ssa.Val
        return res
 }
 
+// isStackAddr returns whether v is known to be an address of a stack slot
+func isStackAddr(v *ssa.Value) bool {
+       for v.Op == ssa.OpOffPtr || v.Op == ssa.OpAddPtr || v.Op == ssa.OpPtrIndex || v.Op == ssa.OpCopy {
+               v = v.Args[0]
+       }
+       switch v.Op {
+       case ssa.OpSP:
+               return true
+       case ssa.OpAddr:
+               return v.Args[0].Op == ssa.OpSP
+       }
+       return false
+}
+
 // insertWBmove inserts the assignment *left = *right including a write barrier.
 // t is the type being assigned.
 func (s *state) insertWBmove(t *Type, left, right *ssa.Value, line int32, rightIsVolatile bool) {