cmd/compile: output stack map index everywhere it changes

Currently, the code generator only considers outputting stack map
indexes at CALL instructions. Raise this into the code generator loop
itself so that changes in the stack map index at any instruction emit
a PCDATA Prog before the actual instruction.

We'll optimize this in later CLs:

name        old time/op       new time/op       delta
Template          190ms ± 2%        191ms ± 2%    ~     (p=0.529 n=10+10)
Unicode          96.4ms ± 1%       98.5ms ± 3%  +2.18%  (p=0.001 n=9+10)
GoTypes           669ms ± 1%        673ms ± 1%  +0.62%  (p=0.004 n=9+9)
Compiler          3.18s ± 1%        3.22s ± 1%  +1.06%  (p=0.000 n=10+9)
SSA               7.59s ± 1%        7.64s ± 1%  +0.66%  (p=0.023 n=10+10)
Flate             128ms ± 1%        130ms ± 2%  +1.07%  (p=0.043 n=10+10)
GoParser          157ms ± 2%        158ms ± 3%    ~     (p=0.123 n=10+10)
Reflect           442ms ± 1%        445ms ± 1%  +0.73%  (p=0.017 n=10+9)
Tar               179ms ± 1%        180ms ± 1%  +0.58%  (p=0.019 n=9+9)
XML               229ms ± 1%        232ms ± 2%  +1.27%  (p=0.009 n=10+10)
[Geo mean]        401ms             405ms       +0.94%

name        old exe-bytes     new exe-bytes     delta
HelloSize         1.46M ± 0%        1.47M ± 0%  +0.84%  (p=0.000 n=10+10)
[Geo mean]        1.46M             1.47M       +0.84%

For #24543.

Change-Id: I4bfe45b767c9d9db47308a27763b303fa75bfa54
Reviewed-on: https://go-review.googlesource.com/109350
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Austin Clements 2018-03-27 16:11:10 -04:00
parent a367f44c18
commit ed7a0682e2
3 changed files with 26 additions and 5 deletions

View file

@ -49,6 +49,9 @@ type Progs struct {
curfn *Node // fn these Progs are for
progcache []obj.Prog // local progcache
cacheidx int // first free element of progcache
nextLive LivenessIndex // liveness index for the next Prog
prevLive LivenessIndex // last emitted liveness index
}
// newProgs returns a new Progs for fn.
@ -67,6 +70,8 @@ func newProgs(fn *Node, worker int) *Progs {
pp.pos = fn.Pos
pp.settext(fn)
pp.nextLive = LivenessInvalid
pp.prevLive = LivenessInvalid
return pp
}
@ -103,6 +108,15 @@ func (pp *Progs) Free() {
// Prog adds a Prog with instruction As to pp.
func (pp *Progs) Prog(as obj.As) *obj.Prog {
if pp.nextLive.stackMapIndex != pp.prevLive.stackMapIndex {
// Emit stack map index change.
idx := pp.nextLive.stackMapIndex
pp.prevLive.stackMapIndex = idx
p := pp.Prog(obj.APCDATA)
Addrconst(&p.From, objabi.PCDATA_StackMapIndex)
Addrconst(&p.To, int64(idx))
}
p := pp.next
pp.next = pp.NewProg()
pp.clearp(pp.next)

View file

@ -153,7 +153,13 @@ type LivenessIndex struct {
}
// LivenessInvalid indicates an unsafe point.
var LivenessInvalid = LivenessIndex{-1}
//
// We use index -2 because PCDATA tables conventionally start at -1,
// so -1 is used to mean the entry liveness map (which is actually at
// index 0; sigh). TODO(austin): Maybe we should use PCDATA+1 as the
// index into the liveness map so -1 uniquely refers to the entry
// liveness map.
var LivenessInvalid = LivenessIndex{-2}
func (idx LivenessIndex) Valid() bool {
return idx.stackMapIndex >= 0

View file

@ -15,7 +15,6 @@ import (
"cmd/compile/internal/ssa"
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/src"
"cmd/internal/sys"
)
@ -4818,12 +4817,17 @@ func genssa(f *ssa.Func, pp *Progs) {
// Emit basic blocks
for i, b := range f.Blocks {
s.bstart[b.ID] = s.pp.next
s.pp.nextLive = LivenessInvalid
s.lineRunStart = nil
// Emit values in block
thearch.SSAMarkMoves(&s, b)
for _, v := range b.Values {
x := s.pp.next
s.DebugFriendlySetPosFrom(v)
// Attach this safe point to the next
// instruction.
s.pp.nextLive = s.livenessMap.Get(v)
switch v.Op {
case ssa.OpInitMem:
// memory arg needs no code
@ -5279,9 +5283,6 @@ func (s *SSAGenState) PrepareCall(v *ssa.Value) {
Fatalf("missing stack map index for %v", v.LongString())
}
}
p := s.Prog(obj.APCDATA)
Addrconst(&p.From, objabi.PCDATA_StackMapIndex)
Addrconst(&p.To, int64(idx.stackMapIndex))
if sym, _ := v.Aux.(*obj.LSym); sym == Deferreturn {
// Deferred calls will appear to be returning to