From ce584e516e79c2b4a3fc9570db695d2d4629485a Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Fri, 17 Mar 2017 11:53:24 -0400 Subject: [PATCH] cmd/compile: using a single Store op for non-pointer non-skip store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes fewer Values around until decomposing, reducing allocation in compiler. name old alloc/op new alloc/op delta Template 41.4MB ± 0% 40.8MB ± 0% -1.29% (p=0.000 n=10+10) Unicode 30.3MB ± 0% 30.2MB ± 0% -0.24% (p=0.000 n=10+10) GoTypes 118MB ± 0% 115MB ± 0% -2.23% (p=0.000 n=10+10) Compiler 505MB ± 0% 493MB ± 0% -2.47% (p=0.000 n=10+10) SSA 881MB ± 0% 872MB ± 0% -1.03% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Template 401k ± 1% 400k ± 1% ~ (p=0.631 n=10+10) Unicode 321k ± 0% 321k ± 1% ~ (p=0.684 n=10+10) GoTypes 1.18M ± 0% 1.17M ± 0% -0.34% (p=0.000 n=10+10) Compiler 4.63M ± 0% 4.61M ± 0% -0.43% (p=0.000 n=10+10) SSA 7.83M ± 0% 7.82M ± 0% -0.13% (p=0.000 n=10+10) Change-Id: I8f736396294444248a439bd4c90be1357024ce88 Reviewed-on: https://go-review.googlesource.com/38294 Run-TryBot: Cherry Zhang Reviewed-by: Josh Bleecher Snyder --- src/cmd/compile/internal/gc/ssa.go | 8 ++++++++ src/cmd/compile/internal/ssa/writebarrier.go | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index 587bb7e2fbc..f1447009da4 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -3417,9 +3417,17 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*Type, args ...*ssa // do *left = right for type t. func (s *state) storeType(t *Type, left, right *ssa.Value, skip skipMask) { + if skip == 0 && (!haspointers(t) || ssa.IsStackAddr(left)) { + // Known to not have write barrier. Store the whole type. + s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, t, left, right, s.mem()) + return + } + // store scalar fields first, so write barrier stores for // pointer fields can be grouped together, and scalar values // don't need to be live across the write barrier call. + // TODO: if the writebarrier pass knows how to reorder stores, + // we can do a single store here as long as skip==0. s.storeTypeScalars(t, left, right, skip) if skip&skipPtr == 0 && haspointers(t) { s.storeTypePtrs(t, left, right) diff --git a/src/cmd/compile/internal/ssa/writebarrier.go b/src/cmd/compile/internal/ssa/writebarrier.go index 3447540309e..43349bfaf52 100644 --- a/src/cmd/compile/internal/ssa/writebarrier.go +++ b/src/cmd/compile/internal/ssa/writebarrier.go @@ -19,7 +19,7 @@ func needwb(v *Value) bool { if !t.HasPointer() { return false } - if isStackAddr(v.Args[0]) { + if IsStackAddr(v.Args[0]) { return false // write on stack doesn't need write barrier } return true @@ -316,8 +316,8 @@ func round(o int64, r int64) int64 { return (o + r - 1) &^ (r - 1) } -// isStackAddr returns whether v is known to be an address of a stack slot -func isStackAddr(v *Value) bool { +// IsStackAddr returns whether v is known to be an address of a stack slot +func IsStackAddr(v *Value) bool { for v.Op == OpOffPtr || v.Op == OpAddPtr || v.Op == OpPtrIndex || v.Op == OpCopy { v = v.Args[0] }