mirror of
https://github.com/golang/go
synced 2024-11-18 05:04:47 -07:00
cmd/compile: introduce LivenessMap and LivenessIndex
Currently liveness only produces a stack map index at each safe point, so the information is summarized in a map[*ssa.Value]int. We're about to have both a stack map index and a register map index, so replace the int with a LivenessIndex type we can extend, and replace the map with a LivenessMap that we can also change more easily in the future. This also gives us an easy hook for defining the value that means "not a safe point". Passes toolstash -cmp. For #24543. Change-Id: Ic4c069839635efed4fd0f603899b80f8be3b56ec Reviewed-on: https://go-review.googlesource.com/109347 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:
parent
02495da6b6
commit
d7d9df8a5b
@ -120,14 +120,42 @@ type Liveness struct {
|
||||
// Indexed sequentially by safe points in Block and Value order.
|
||||
livevars []bvec
|
||||
|
||||
// stackMapIndex maps from safe points (i.e., CALLs) to their
|
||||
// index within stackMaps.
|
||||
stackMapIndex map[*ssa.Value]int
|
||||
stackMaps []bvec
|
||||
// livenessMap maps from safe points (i.e., CALLs) to their
|
||||
// liveness map indexes.
|
||||
//
|
||||
// TODO(austin): Now that we have liveness at almost every PC,
|
||||
// should this be a dense structure?
|
||||
livenessMap LivenessMap
|
||||
stackMaps []bvec
|
||||
|
||||
cache progeffectscache
|
||||
}
|
||||
|
||||
// LivenessMap maps from *ssa.Value to LivenessIndex.
|
||||
type LivenessMap struct {
|
||||
m map[*ssa.Value]LivenessIndex
|
||||
}
|
||||
|
||||
func (m LivenessMap) Get(v *ssa.Value) LivenessIndex {
|
||||
if i, ok := m.m[v]; ok {
|
||||
return i
|
||||
}
|
||||
// Not a safe point.
|
||||
return LivenessInvalid
|
||||
}
|
||||
|
||||
// LivenessIndex stores the liveness map index for a safe-point.
|
||||
type LivenessIndex struct {
|
||||
stackMapIndex int
|
||||
}
|
||||
|
||||
// LivenessInvalid indicates an unsafe point.
|
||||
var LivenessInvalid = LivenessIndex{-1}
|
||||
|
||||
func (idx LivenessIndex) Valid() bool {
|
||||
return idx.stackMapIndex >= 0
|
||||
}
|
||||
|
||||
type progeffectscache struct {
|
||||
textavarinit []int32
|
||||
retuevar []int32
|
||||
@ -817,10 +845,10 @@ func (lv *Liveness) clobber() {
|
||||
before = false
|
||||
}
|
||||
if before {
|
||||
clobber(lv, b, lv.stackMaps[lv.stackMapIndex[v]])
|
||||
clobber(lv, b, lv.stackMaps[lv.livenessMap.Get(v).stackMapIndex])
|
||||
}
|
||||
b.Values = append(b.Values, v)
|
||||
clobber(lv, b, lv.stackMaps[lv.stackMapIndex[v]])
|
||||
clobber(lv, b, lv.stackMaps[lv.livenessMap.Get(v).stackMapIndex])
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1006,12 +1034,12 @@ Outer:
|
||||
// These will later become PCDATA instructions.
|
||||
lv.showlive(nil, lv.stackMaps[0])
|
||||
pos := 1
|
||||
lv.stackMapIndex = make(map[*ssa.Value]int)
|
||||
lv.livenessMap = LivenessMap{make(map[*ssa.Value]LivenessIndex)}
|
||||
for _, b := range lv.f.Blocks {
|
||||
for _, v := range b.Values {
|
||||
if issafepoint(v) {
|
||||
lv.showlive(v, lv.stackMaps[remap[pos]])
|
||||
lv.stackMapIndex[v] = remap[pos]
|
||||
lv.livenessMap.m[v] = LivenessIndex{remap[pos]}
|
||||
pos++
|
||||
}
|
||||
}
|
||||
@ -1153,8 +1181,8 @@ func (lv *Liveness) printDebug() {
|
||||
for _, v := range b.Values {
|
||||
fmt.Printf("(%s) %v\n", linestr(v.Pos), v.LongString())
|
||||
|
||||
if pos, ok := lv.stackMapIndex[v]; ok {
|
||||
pcdata = pos
|
||||
if pos := lv.livenessMap.Get(v); pos.Valid() {
|
||||
pcdata = pos.stackMapIndex
|
||||
}
|
||||
|
||||
pos, effect := lv.valueEffects(v)
|
||||
@ -1265,7 +1293,7 @@ func (lv *Liveness) emit(argssym, livesym *obj.LSym) {
|
||||
// pointer variables in the function and emits a runtime data
|
||||
// structure read by the garbage collector.
|
||||
// Returns a map from GC safe points to their corresponding stack map index.
|
||||
func liveness(e *ssafn, f *ssa.Func) map[*ssa.Value]int {
|
||||
func liveness(e *ssafn, f *ssa.Func) LivenessMap {
|
||||
// Construct the global liveness state.
|
||||
vars, idx := getvariables(e.curfn)
|
||||
lv := newliveness(e.curfn, f, vars, idx, e.stkptrsize)
|
||||
@ -1284,5 +1312,5 @@ func liveness(e *ssafn, f *ssa.Func) map[*ssa.Value]int {
|
||||
if ls := e.curfn.Func.lsym; ls != nil {
|
||||
lv.emit(&ls.Func.GCArgs, &ls.Func.GCLocals)
|
||||
}
|
||||
return lv.stackMapIndex
|
||||
return lv.livenessMap
|
||||
}
|
||||
|
@ -4694,9 +4694,9 @@ type SSAGenState struct {
|
||||
|
||||
maxarg int64 // largest frame size for arguments to calls made by the function
|
||||
|
||||
// Map from GC safe points to stack map index, generated by
|
||||
// Map from GC safe points to liveness index, generated by
|
||||
// liveness analysis.
|
||||
stackMapIndex map[*ssa.Value]int
|
||||
livenessMap LivenessMap
|
||||
|
||||
// lineRunStart records the beginning of the current run of instructions
|
||||
// within a single block sharing the same line number
|
||||
@ -4772,7 +4772,7 @@ func genssa(f *ssa.Func, pp *Progs) {
|
||||
|
||||
e := f.Frontend().(*ssafn)
|
||||
|
||||
s.stackMapIndex = liveness(e, f)
|
||||
s.livenessMap = liveness(e, f)
|
||||
|
||||
// Remember where each block starts.
|
||||
s.bstart = make([]*obj.Prog, f.NumBlocks())
|
||||
@ -5270,13 +5270,13 @@ func (s *SSAGenState) Call(v *ssa.Value) *obj.Prog {
|
||||
// It must be called immediately before emitting the actual CALL instruction,
|
||||
// since it emits PCDATA for the stack map at the call (calls are safe points).
|
||||
func (s *SSAGenState) PrepareCall(v *ssa.Value) {
|
||||
idx, ok := s.stackMapIndex[v]
|
||||
if !ok {
|
||||
idx := s.livenessMap.Get(v)
|
||||
if !idx.Valid() {
|
||||
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))
|
||||
Addrconst(&p.To, int64(idx.stackMapIndex))
|
||||
|
||||
if sym, _ := v.Aux.(*obj.LSym); sym == Deferreturn {
|
||||
// Deferred calls will appear to be returning to
|
||||
|
Loading…
Reference in New Issue
Block a user