From: Josh Bleecher Snyder Date: Thu, 15 Feb 2018 03:05:36 +0000 (-0800) Subject: cmd/compile: prevent memmove in copy when dst == src X-Git-Tag: go1.11beta1~1412 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=91a05b92bedc976009b967d3e3bcbbe6353eb4a6;p=gostls13.git cmd/compile: prevent memmove in copy when dst == src This causes a nominal increase in binary size. name old object-bytes new object-bytes delta Template 399kB ± 0% 399kB ± 0% ~ (all equal) Unicode 207kB ± 0% 207kB ± 0% ~ (all equal) GoTypes 1.23MB ± 0% 1.23MB ± 0% ~ (all equal) Compiler 4.35MB ± 0% 4.35MB ± 0% +0.01% (p=0.008 n=5+5) SSA 9.77MB ± 0% 9.77MB ± 0% +0.00% (p=0.008 n=5+5) Flate 236kB ± 0% 236kB ± 0% +0.04% (p=0.008 n=5+5) GoParser 298kB ± 0% 298kB ± 0% ~ (all equal) Reflect 1.03MB ± 0% 1.03MB ± 0% +0.01% (p=0.008 n=5+5) Tar 333kB ± 0% 334kB ± 0% +0.22% (p=0.008 n=5+5) XML 414kB ± 0% 414kB ± 0% +0.02% (p=0.008 n=5+5) [Geo mean] 730kB 731kB +0.03% Change-Id: I381809fd9cfbfd6db44bd342b06285e62a3a21f1 Reviewed-on: https://go-review.googlesource.com/94596 Run-TryBot: Josh Bleecher Snyder Reviewed-by: Keith Randall --- diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 7925e09c80..ab113daec4 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -3135,7 +3135,7 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node { // init { // n := len(a) // if n > len(b) { n = len(b) } -// memmove(a.ptr, b.ptr, n*sizeof(elem(a))) +// if a.ptr != b.ptr { memmove(a.ptr, b.ptr, n*sizeof(elem(a))) } // } // n; // @@ -3183,14 +3183,19 @@ func copyany(n *Node, init *Nodes, runtimecall bool) *Node { nif.Nbody.Append(nod(OAS, nlen, nod(OLEN, nr, nil))) l = append(l, nif) - // Call memmove. - fn := syslook("memmove") + // if to.ptr != frm.ptr { memmove( ... ) } + ne := nod(OIF, nod(ONE, nto, nfrm), nil) + ne.SetLikely(true) + l = append(l, ne) + fn := syslook("memmove") fn = substArgTypes(fn, nl.Type.Elem(), nl.Type.Elem()) nwid := temp(types.Types[TUINTPTR]) - l = append(l, nod(OAS, nwid, conv(nlen, types.Types[TUINTPTR]))) + setwid := nod(OAS, nwid, conv(nlen, types.Types[TUINTPTR])) + ne.Nbody.Append(setwid) nwid = nod(OMUL, nwid, nodintconst(nl.Type.Elem().Width)) - l = append(l, mkcall1(fn, nil, init, nto, nfrm, nwid)) + call := mkcall1(fn, nil, init, nto, nfrm, nwid) + ne.Nbody.Append(call) typecheckslice(l, Etop) walkstmtlist(l)