]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: output stack map index everywhere it changes
authorAustin Clements <austin@google.com>
Tue, 27 Mar 2018 20:11:10 +0000 (16:11 -0400)
committerAustin Clements <austin@google.com>
Tue, 22 May 2018 14:43:38 +0000 (14:43 +0000)
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>
src/cmd/compile/internal/gc/gsubr.go
src/cmd/compile/internal/gc/plive.go
src/cmd/compile/internal/gc/ssa.go

index 55b16792f97d10ea46804d25dc8c81b514f5b12f..70b5cd3366d27e0caa06bff371bf485708dc3073 100644 (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)
index 456a2f76522c81f1ebe37bb47414ac143d2e519d..7a953546dcfca941966673178bf410a724b06f97 100644 (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
index 09d12cba1efbdcfc70f392952a8e39616a6879e3..b280fb73974fea75d28689f8ee4bb7fed57a3515 100644 (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