]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: make LivenessMap sparse
authorAustin Clements <austin@google.com>
Mon, 27 Apr 2020 23:18:48 +0000 (19:18 -0400)
committerAustin Clements <austin@google.com>
Wed, 29 Apr 2020 21:29:20 +0000 (21:29 +0000)
We're about to switch to having significantly fewer maps in the
liveness map, so switch from a dense representation to a sparse
representation.

Passes toolstash-check.

For #36365.

Change-Id: Icb17bd6ace17667a280bc5fba4039cae3020a8d1
Reviewed-on: https://go-review.googlesource.com/c/go/+/230543
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/gc/plive.go

index 707ceca33a367d3df074cdb0d2769dcaaf73a2a3..f8ccdd23695086a5e4d207a832a8119b17d708b6 100644 (file)
@@ -147,32 +147,29 @@ type openDeferVarInfo struct {
 
 // LivenessMap maps from *ssa.Value to LivenessIndex.
 type LivenessMap struct {
-       m []LivenessIndex
+       vals map[ssa.ID]LivenessIndex
 }
 
-func (m *LivenessMap) reset(ids int) {
-       m2 := m.m
-       if ids > cap(m2) {
-               m2 = make([]LivenessIndex, ids)
+func (m *LivenessMap) reset() {
+       if m.vals == nil {
+               m.vals = make(map[ssa.ID]LivenessIndex)
        } else {
-               m2 = m2[:ids]
-       }
-       none := LivenessInvalid
-       for i := range m2 {
-               m2[i] = none
+               for k := range m.vals {
+                       delete(m.vals, k)
+               }
        }
-       m.m = m2
 }
 
 func (m *LivenessMap) set(v *ssa.Value, i LivenessIndex) {
-       m.m[v.ID] = i
+       m.vals[v.ID] = i
 }
 
 func (m LivenessMap) Get(v *ssa.Value) LivenessIndex {
-       if int(v.ID) < len(m.m) {
-               return m.m[int(v.ID)]
+       // All safe-points are in the map, so if v isn't in
+       // the map, it's an unsafe-point.
+       if idx, ok := m.vals[v.ID]; ok {
+               return idx
        }
-       // Not a safe point.
        return LivenessInvalid
 }
 
@@ -515,7 +512,7 @@ func newliveness(fn *Node, f *ssa.Func, vars []*Node, idx map[*Node]int32, stkpt
 
        // Significant sources of allocation are kept in the ssa.Cache
        // and reused. Surprisingly, the bit vectors themselves aren't
-       // a major source of allocation, but the slices are.
+       // a major source of allocation, but the liveness maps are.
        if lc, _ := f.Cache.Liveness.(*livenessFuncCache); lc == nil {
                // Prep the cache so liveness can fill it later.
                f.Cache.Liveness = new(livenessFuncCache)
@@ -523,7 +520,8 @@ func newliveness(fn *Node, f *ssa.Func, vars []*Node, idx map[*Node]int32, stkpt
                if cap(lc.be) >= f.NumBlocks() {
                        lv.be = lc.be[:f.NumBlocks()]
                }
-               lv.livenessMap = LivenessMap{lc.livenessMap.m[:0]}
+               lv.livenessMap = LivenessMap{lc.livenessMap.vals}
+               lc.livenessMap.vals = nil
        }
        if lv.be == nil {
                lv.be = make([]BlockEffects, f.NumBlocks())
@@ -540,7 +538,7 @@ func newliveness(fn *Node, f *ssa.Func, vars []*Node, idx map[*Node]int32, stkpt
                be.livein = varRegVec{vars: bulk.next()}
                be.liveout = varRegVec{vars: bulk.next()}
        }
-       lv.livenessMap.reset(lv.f.NumValues())
+       lv.livenessMap.reset()
 
        lv.markUnsafePoints()
        return lv
@@ -1559,7 +1557,7 @@ func liveness(e *ssafn, f *ssa.Func, pp *Progs) LivenessMap {
                        }
                        cache.be = lv.be
                }
-               if cap(lv.livenessMap.m) < 2000 {
+               if len(lv.livenessMap.vals) < 2000 {
                        cache.livenessMap = lv.livenessMap
                }
        }