1
0
mirror of https://github.com/golang/go synced 2024-11-18 11:55:01 -07:00

cmd/compile: make LivenessMap sparse

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>
This commit is contained in:
Austin Clements 2020-04-27 19:18:48 -04:00
parent 601bc41da2
commit ee7d9f1c37

View 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]
for k := range m.vals {
delete(m.vals, k)
}
}
none := LivenessInvalid
for i := range m2 {
m2[i] = none
}
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
}
}