]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: simplify needwritebarrier
authorMatthew Dempsky <mdempsky@google.com>
Thu, 16 Feb 2017 02:43:34 +0000 (18:43 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 16 Feb 2017 22:42:36 +0000 (22:42 +0000)
Currently, whether we need a write barrier is simply a property of the
pointer slot being written to.

The only optimization we currently apply using the value being written
is that pointers to stack variables can omit write barriers because
they're only written to stack slots... but we already omit write
barriers for all writes to the stack anyway.

Passes toolstash -cmp.

Change-Id: I7f16b71ff473899ed96706232d371d5b2b7ae789
Reviewed-on: https://go-review.googlesource.com/37109
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/gc/walk.go

index 505611e6ae5db8960275170b8d02e64fb93d1aac..b9b3b80b52785aa5b96544b05aaf7d08b349a123 100644 (file)
@@ -553,7 +553,7 @@ func (s *state) stmt(n *Node) {
                        deref = true
                        res = res.Args[0]
                }
-               s.assign(n.List.First(), res, needwritebarrier(n.List.First(), n.Rlist.First()), deref, 0, false)
+               s.assign(n.List.First(), res, needwritebarrier(n.List.First()), deref, 0, false)
                s.assign(n.List.Second(), resok, false, false, 0, false)
                return
 
@@ -565,12 +565,8 @@ func (s *state) stmt(n *Node) {
                v := s.intrinsicCall(n.Rlist.First())
                v1 := s.newValue1(ssa.OpSelect0, n.List.First().Type, v)
                v2 := s.newValue1(ssa.OpSelect1, n.List.Second().Type, v)
-               // Make a fake node to mimic loading return value, ONLY for write barrier test.
-               // This is future-proofing against non-scalar 2-result intrinsics.
-               // Currently we only have scalar ones, which result in no write barrier.
-               fakeret := &Node{Op: OINDREGSP}
-               s.assign(n.List.First(), v1, needwritebarrier(n.List.First(), fakeret), false, 0, false)
-               s.assign(n.List.Second(), v2, needwritebarrier(n.List.Second(), fakeret), false, 0, false)
+               s.assign(n.List.First(), v1, needwritebarrier(n.List.First()), false, 0, false)
+               s.assign(n.List.Second(), v2, needwritebarrier(n.List.Second()), false, 0, false)
                return
 
        case ODCL:
@@ -696,7 +692,7 @@ func (s *state) stmt(n *Node) {
                }
                var r *ssa.Value
                var isVolatile bool
-               needwb := n.Right != nil && needwritebarrier(n.Left, n.Right)
+               needwb := n.Right != nil && needwritebarrier(n.Left)
                deref := !canSSAType(t)
                if deref {
                        if rhs == nil {
@@ -711,7 +707,7 @@ func (s *state) stmt(n *Node) {
                                r = s.expr(rhs)
                        }
                }
-               if rhs != nil && rhs.Op == OAPPEND && needwritebarrier(n.Left, rhs) {
+               if rhs != nil && rhs.Op == OAPPEND && needwritebarrier(n.Left) {
                        // The frontend gets rid of the write barrier to enable the special OAPPEND
                        // handling above, but since this is not a special case, we need it.
                        // TODO: just add a ptr graying to the end of growslice?
index c7b81858cccc8679003fbfe06e0e6a8493c2056d..98aebc528e8d22da46b461fdcdcdbb6a565bbbf8 100644 (file)
@@ -1170,7 +1170,7 @@ func ullmancalc(n *Node) {
                goto out
 
        case OAS:
-               if !needwritebarrier(n.Left, n.Right) {
+               if !needwritebarrier(n.Left) {
                        break
                }
                fallthrough
index 28b430f22dd307d8c0995d17091dd9c4c0819561..b82618af6bb6a9669af32d7be8ed8ea7bc542cde 100644 (file)
@@ -1664,8 +1664,7 @@ func fncall(l *Node, rt *Type) bool {
        if l.Ullman >= UINF || l.Op == OINDEXMAP {
                return true
        }
-       var r Node
-       if needwritebarrier(l, &r) {
+       if needwritebarrier(l) {
                return true
        }
        if eqtype(l.Type, rt) {
@@ -2049,8 +2048,8 @@ func isstack(n *Node) bool {
        return false
 }
 
-// Do we need a write barrier for the assignment l = r?
-func needwritebarrier(l *Node, r *Node) bool {
+// Do we need a write barrier for assigning to l?
+func needwritebarrier(l *Node) bool {
        if !use_writebarrier {
                return false
        }
@@ -2077,21 +2076,6 @@ func needwritebarrier(l *Node, r *Node) bool {
                return false
        }
 
-       // Implicit zeroing is still zeroing, so it needs write
-       // barriers. In practice, these are all to stack variables
-       // (even if isstack isn't smart enough to figure that out), so
-       // they'll be eliminated by the backend.
-       if r == nil {
-               return true
-       }
-
-       // Ignore no-op conversions when making decision.
-       // Ensures that xp = unsafe.Pointer(&x) is treated
-       // the same as xp = &x.
-       for r.Op == OCONVNOP {
-               r = r.Left
-       }
-
        // TODO: We can eliminate write barriers if we know *both* the
        // current and new content of the slot must already be shaded.
        // We know a pointer is shaded if it's nil, or points to
@@ -2100,12 +2084,6 @@ func needwritebarrier(l *Node, r *Node) bool {
        // writes to just-allocated objects. Unfortunately, knowing
        // the "current" value of the slot requires flow analysis.
 
-       // No write barrier for storing address of stack values,
-       // which are guaranteed only to be written to the stack.
-       if r.Op == OADDR && isstack(r.Left) {
-               return false
-       }
-
        // Otherwise, be conservative and use write barrier.
        return true
 }