mirror of
https://github.com/golang/go
synced 2024-11-18 12:04:57 -07:00
cmd/compile: add OpOffPtr [c] SP to constant cache
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>
This commit is contained in:
parent
d11a2184fb
commit
3dcfce8d19
@ -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()
|
||||
}
|
||||
|
@ -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() }
|
||||
|
Loading…
Reference in New Issue
Block a user