]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: teach CSE that new objects are bespoke
authorJosh Bleecher Snyder <josharian@gmail.com>
Wed, 13 Apr 2016 00:12:26 +0000 (17:12 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 13 Apr 2016 02:11:56 +0000 (02:11 +0000)
runtime.newobject never returns the same thing twice,
so the resulting value will never be a common subexpression.

This helps when compiling large static data structures
that include pointers, such as maps and slices.
No clear performance impact on other code. (See below.)

For the code in issue #15112:

Before:
  real 1m14.238s
  user 1m18.985s
  sys 0m0.787s

After:
  real 0m47.172s
  user 0m52.248s
  sys 0m0.767s

For the code in issue #15235, size 10k:

Before:
  real 0m44.916s
  user 0m46.577s
  sys 0m0.304s

After:
  real 0m7.703s
  user 0m9.041s
  sys 0m0.316s

Still more work to be done, particularly for #15112.

Updates #15112
Updates #15235

name       old time/op      new time/op      delta
Template        330ms ±11%       333ms ±13%    ~           (p=0.749 n=20+19)
Unicode         148ms ± 6%       152ms ± 8%    ~           (p=0.072 n=18+20)
GoTypes         1.01s ± 7%       1.01s ± 3%    ~           (p=0.583 n=20+20)
Compiler        5.04s ± 2%       5.06s ± 2%    ~           (p=0.314 n=20+20)

name       old user-ns/op   new user-ns/op   delta
Template   444user-ms ±11%  445user-ms ±10%    ~           (p=0.738 n=20+20)
Unicode    215user-ms ± 5%  218user-ms ± 5%    ~           (p=0.239 n=18+18)
GoTypes    1.45user-s ± 3%  1.45user-s ± 4%    ~           (p=0.620 n=20+20)
Compiler   7.23user-s ± 2%  7.22user-s ± 2%    ~           (p=0.901 n=20+19)

name       old alloc/op     new alloc/op     delta
Template       55.0MB ± 0%      55.0MB ± 0%    ~           (p=0.547 n=20+20)
Unicode        37.6MB ± 0%      37.6MB ± 0%    ~           (p=0.301 n=20+20)
GoTypes         177MB ± 0%       177MB ± 0%    ~           (p=0.065 n=20+19)
Compiler        798MB ± 0%       797MB ± 0%  -0.05%        (p=0.000 n=19+20)

name       old allocs/op    new allocs/op    delta
Template         492k ± 0%        493k ± 0%  +0.03%        (p=0.030 n=20+20)
Unicode          377k ± 0%        377k ± 0%    ~           (p=0.423 n=20+19)
GoTypes         1.40M ± 0%       1.40M ± 0%    ~           (p=0.102 n=20+20)
Compiler        5.53M ± 0%       5.53M ± 0%    ~           (p=0.094 n=17+18)

name       old text-bytes   new text-bytes   delta
HelloSize        561k ± 0%        561k ± 0%    ~     (all samples are equal)
CmdGoSize       6.13M ± 0%       6.13M ± 0%    ~     (all samples are equal)

name       old data-bytes   new data-bytes   delta
HelloSize        128k ± 0%        128k ± 0%    ~     (all samples are equal)
CmdGoSize        306k ± 0%        306k ± 0%    ~     (all samples are equal)

name       old exe-bytes    new exe-bytes    delta
HelloSize        905k ± 0%        905k ± 0%    ~     (all samples are equal)
CmdGoSize       9.64M ± 0%       9.64M ± 0%    ~     (all samples are equal)

Change-Id: Id774e2901d7701a3ec7a1c1d1cf1d9327a4107fc
Reviewed-on: https://go-review.googlesource.com/21937
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Todd Neal <todd@tneal.org>
src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/ssa/config.go
src/cmd/compile/internal/ssa/cse.go

index 035bd815c2f999aaa294f106f59e345f509da650..091762f49648389dc558afa2b84a92d03d12ad1b 100644 (file)
@@ -1081,6 +1081,10 @@ func syslook(name string) *Node {
        return s.Def
 }
 
+func (s *Sym) IsRuntimeCall(name string) bool {
+       return s.Pkg == Runtimepkg && s.Name == name
+}
+
 // typehash computes a hash value for type t to use in type switch
 // statements.
 func typehash(t *Type) uint32 {
index 2a676e39b3a1f7031581c76df91b5cabe5cc25ec..a60291ea53906cb59e5f19986d7a05dd3f818882 100644 (file)
@@ -116,6 +116,12 @@ type GCNode interface {
        String() string
 }
 
+// GCSym is an interface that *gc.Sym implements.
+// Using *gc.Sym directly would lead to import cycles.
+type GCSym interface {
+       IsRuntimeCall(name string) bool
+}
+
 // NewConfig returns a new configuration object for the given architecture.
 func NewConfig(arch string, fe Frontend, ctxt *obj.Link, optimize bool) *Config {
        c := &Config{arch: arch, fe: fe}
index 1ec5712be022d9a7900d1707be1436a2cd89388c..9853ff06d040d256feab5fd47ea2d5357e0ff45a 100644 (file)
@@ -255,6 +255,14 @@ func cmpVal(v, w *Value, auxIDs auxmap, depth int) Cmp {
                return lt2Cmp(v.Block.ID < w.Block.ID)
        }
 
+       switch v.Op {
+       case OpStaticCall, OpAMD64CALLstatic, OpARMCALLstatic:
+               sym := v.Aux.(GCSym)
+               if sym.IsRuntimeCall("newobject") {
+                       return lt2Cmp(v.ID < w.ID)
+               }
+       }
+
        if tc := v.Type.Compare(w.Type); tc != CMPeq {
                return tc
        }