From 68331750dac5a38c5158f57ab19e3e99d11a59e3 Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Mon, 3 Oct 2016 23:01:26 -0400 Subject: [PATCH] cmd/compile: remove some write barriers for stack writes 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 TryBot-Result: Gobot Gobot Reviewed-by: David Chase --- src/cmd/compile/internal/gc/ssa.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index e4eefd22a7..8e9e915fd4 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -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) {