]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add OpOffPtr [c] SP to constant cache
authorJosh Bleecher Snyder <josharian@gmail.com>
Wed, 8 Mar 2017 20:50:00 +0000 (12:50 -0800)
committerJosh Bleecher Snyder <josharian@gmail.com>
Fri, 10 Mar 2017 16:50:58 +0000 (16:50 +0000)
They accounted for almost 30% of all CSE'd values.

By never creating the duplicates in the first place,
we reduce the high water mark of Value IDs,
which in turn makes all SSA phases cheaper,
particularly regalloc.

name       old time/op     new time/op     delta
Template       200ms ± 3%      198ms ± 4%  -0.87%  (p=0.016 n=50+49)
Unicode       86.9ms ± 2%     85.5ms ± 3%  -1.56%  (p=0.000 n=49+50)
GoTypes        553ms ± 4%      551ms ± 4%    ~     (p=0.183 n=50+49)
SSA            3.97s ± 3%      3.93s ± 2%  -1.06%  (p=0.000 n=48+48)
Flate          124ms ± 4%      124ms ± 3%    ~     (p=0.545 n=48+50)
GoParser       146ms ± 4%      146ms ± 4%    ~     (p=0.810 n=49+49)
Reflect        357ms ± 3%      355ms ± 3%  -0.59%  (p=0.049 n=50+48)
Tar            106ms ± 4%      107ms ± 5%    ~     (p=0.454 n=49+50)
XML            203ms ± 4%      203ms ± 4%    ~     (p=0.726 n=48+50)

name       old user-ns/op  new user-ns/op  delta
Template        237M ± 3%       235M ± 4%    ~     (p=0.208 n=47+48)
Unicode         111M ± 4%       108M ± 9%  -2.50%  (p=0.000 n=47+50)
GoTypes         736M ± 5%       729M ± 4%  -0.95%  (p=0.017 n=50+46)
SSA            5.73G ± 4%      5.74G ± 4%    ~     (p=0.765 n=50+50)
Flate           150M ± 5%       148M ± 6%  -0.89%  (p=0.045 n=48+47)
GoParser        180M ± 5%       178M ± 7%  -1.34%  (p=0.012 n=50+50)
Reflect         450M ± 4%       444M ± 4%  -1.40%  (p=0.000 n=50+49)
Tar             124M ± 7%       123M ± 7%    ~     (p=0.092 n=50+50)
XML             248M ± 6%       245M ± 5%    ~     (p=0.057 n=50+50)

name       old alloc/op    new alloc/op    delta
Template      39.4MB ± 0%     39.3MB ± 0%  -0.37%  (p=0.000 n=50+50)
Unicode       30.9MB ± 0%     30.9MB ± 0%  -0.27%  (p=0.000 n=48+50)
GoTypes        114MB ± 0%      113MB ± 0%  -1.03%  (p=0.000 n=50+49)
SSA            882MB ± 0%      865MB ± 0%  -1.95%  (p=0.000 n=49+49)
Flate         25.8MB ± 0%     25.7MB ± 0%  -0.21%  (p=0.000 n=50+50)
GoParser      31.7MB ± 0%     31.6MB ± 0%  -0.33%  (p=0.000 n=50+50)
Reflect       79.7MB ± 0%     79.3MB ± 0%  -0.49%  (p=0.000 n=44+49)
Tar           27.2MB ± 0%     27.1MB ± 0%  -0.31%  (p=0.000 n=50+50)
XML           42.7MB ± 0%     42.3MB ± 0%  -1.05%  (p=0.000 n=48+49)

name       old allocs/op   new allocs/op   delta
Template        379k ± 1%       380k ± 1%  +0.26%  (p=0.000 n=50+50)
Unicode         324k ± 1%       324k ± 1%    ~     (p=0.964 n=49+50)
GoTypes        1.14M ± 0%      1.15M ± 0%  +0.14%  (p=0.000 n=50+49)
SSA            7.89M ± 0%      7.89M ± 0%  -0.05%  (p=0.000 n=49+49)
Flate           240k ± 1%       241k ± 1%  +0.27%  (p=0.001 n=50+50)
GoParser        310k ± 1%       311k ± 1%  +0.48%  (p=0.000 n=50+49)
Reflect        1.00M ± 0%      1.00M ± 0%  +0.17%  (p=0.000 n=48+50)
Tar             254k ± 1%       255k ± 1%  +0.23%  (p=0.005 n=50+50)
XML             395k ± 1%       395k ± 1%  +0.19%  (p=0.002 n=49+47)

Change-Id: Iaa8f5f37e23bd81983409f7359f9dcd4dfe2961f
Reviewed-on: https://go-review.googlesource.com/38003
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/ssa/func.go

index c9a5ec42bd467d5d4834a9a83780d277a1b50900..d1fba5514d2203b61fd18281fa03584478706d7f 100644 (file)
@@ -477,6 +477,9 @@ func (s *state) constInt(t ssa.Type, c int64) *ssa.Value {
        }
        return s.constInt32(t, int32(c))
 }
+func (s *state) constOffPtrSP(t ssa.Type, c int64) *ssa.Value {
+       return s.f.ConstOffPtrSP(s.peekPos(), t, c, s.sp)
+}
 
 // stmtList converts the statement list n to SSA and adds it to s.
 func (s *state) stmtList(l Nodes) {
@@ -1953,7 +1956,7 @@ func (s *state) expr(n *Node) *ssa.Value {
                return s.addr(n.Left, n.Bounded())
 
        case OINDREGSP:
-               addr := s.entryNewValue1I(ssa.OpOffPtr, ptrto(n.Type), n.Xoffset, s.sp)
+               addr := s.constOffPtrSP(ptrto(n.Type), n.Xoffset)
                return s.newValue2(ssa.OpLoad, n.Type, addr, s.mem())
 
        case OIND:
@@ -2991,7 +2994,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
                if k != callNormal {
                        argStart += int64(2 * Widthptr)
                }
-               addr := s.entryNewValue1I(ssa.OpOffPtr, ptrto(Types[TUINTPTR]), argStart, s.sp)
+               addr := s.constOffPtrSP(ptrto(Types[TUINTPTR]), argStart)
                s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, rcvr, s.mem())
        }
 
@@ -3000,9 +3003,9 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
                // Write argsize and closure (args to Newproc/Deferproc).
                argStart := Ctxt.FixedFrameSize()
                argsize := s.constInt32(Types[TUINT32], int32(stksize))
-               addr := s.entryNewValue1I(ssa.OpOffPtr, ptrto(Types[TUINT32]), argStart, s.sp)
+               addr := s.constOffPtrSP(ptrto(Types[TUINT32]), argStart)
                s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, 4, addr, argsize, s.mem())
-               addr = s.entryNewValue1I(ssa.OpOffPtr, ptrto(Types[TUINTPTR]), argStart+int64(Widthptr), s.sp)
+               addr = s.constOffPtrSP(ptrto(Types[TUINTPTR]), argStart+int64(Widthptr))
                s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, closure, s.mem())
                stksize += 2 * int64(Widthptr)
        }
@@ -3049,7 +3052,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
                return nil
        }
        fp := res.Field(0)
-       return s.entryNewValue1I(ssa.OpOffPtr, ptrto(fp.Type), fp.Offset+Ctxt.FixedFrameSize(), s.sp)
+       return s.constOffPtrSP(ptrto(fp.Type), fp.Offset+Ctxt.FixedFrameSize())
 }
 
 // etypesign returns the signed-ness of e, for integer/pointer etypes.
@@ -3129,7 +3132,7 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value {
        case OINDREGSP:
                // indirect off REGSP
                // used for storing/loading arguments/returns to/from callees
-               return s.entryNewValue1I(ssa.OpOffPtr, t, n.Xoffset, s.sp)
+               return s.constOffPtrSP(t, n.Xoffset)
        case OINDEX:
                if n.Left.Type.IsSlice() {
                        a := s.expr(n.Left)
@@ -3364,7 +3367,7 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*Type, args ...*ssa
        for _, arg := range args {
                t := arg.Type
                off = Rnd(off, t.Alignment())
-               ptr := s.newValue1I(ssa.OpOffPtr, t.PtrTo(), off, s.sp)
+               ptr := s.constOffPtrSP(t.PtrTo(), off)
                size := t.Size()
                s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, size, ptr, arg, s.mem())
                off += size
@@ -3395,7 +3398,7 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*Type, args ...*ssa
        res := make([]*ssa.Value, len(results))
        for i, t := range results {
                off = Rnd(off, t.Alignment())
-               ptr := s.newValue1I(ssa.OpOffPtr, ptrto(t), off, s.sp)
+               ptr := s.constOffPtrSP(ptrto(t), off)
                res[i] = s.newValue2(ssa.OpLoad, t, ptr, s.mem())
                off += t.Size()
        }
index 069a5996a42e547a368156f274cd8733fc45cd39..b0058760969ba87b2270784e68ce7b20adc99637 100644 (file)
@@ -133,9 +133,9 @@ func (f *Func) freeValue(v *Value) {
        // Clear everything but ID (which we reuse).
        id := v.ID
 
-       // Zero argument values might be cached, so remove them there.
+       // Values with zero arguments and OpOffPtr values might be cached, so remove them there.
        nArgs := opcodeTable[v.Op].argLen
-       if nArgs == 0 {
+       if nArgs == 0 || v.Op == OpOffPtr {
                vv := f.constants[v.AuxInt]
                for i, cv := range vv {
                        if v == cv {
@@ -411,6 +411,14 @@ func (f *Func) ConstEmptyString(pos src.XPos, t Type) *Value {
        v.Aux = ""
        return v
 }
+func (f *Func) ConstOffPtrSP(pos src.XPos, t Type, c int64, sp *Value) *Value {
+       v := f.constVal(pos, OpOffPtr, t, c, true)
+       if len(v.Args) == 0 {
+               v.AddArg(sp)
+       }
+       return v
+
+}
 
 func (f *Func) Logf(msg string, args ...interface{})   { f.Config.Logf(msg, args...) }
 func (f *Func) Log() bool                              { return f.Config.Log() }