mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile/internal/ssa: only store relevant slots in pendingEntries
For functions with many local variables, keeping track of every LocalSlot for every variable is very expensive. Only track the slots that are actually used by a given variable. Change-Id: Iaafbce030a782b8b8c4a0eb7cf025e59af899ea4 Reviewed-on: https://go-review.googlesource.com/92400 Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
a306341db7
commit
9c854d65a3
1 changed files with 22 additions and 15 deletions
|
|
@ -214,10 +214,14 @@ func (state *debugState) initializeCache() {
|
||||||
state.changedVars = make([]bool, len(state.vars))
|
state.changedVars = make([]bool, len(state.vars))
|
||||||
|
|
||||||
// A pending entry per user variable, with space to track each of its pieces.
|
// A pending entry per user variable, with space to track each of its pieces.
|
||||||
if want := len(state.vars) * len(state.slots); cap(state.cache.pendingSlotLocs) < want {
|
nPieces := 0
|
||||||
state.cache.pendingSlotLocs = make([]VarLoc, want)
|
for i := range state.varSlots {
|
||||||
|
nPieces += len(state.varSlots[i])
|
||||||
}
|
}
|
||||||
psl := state.cache.pendingSlotLocs[:len(state.vars)*len(state.slots)]
|
if cap(state.cache.pendingSlotLocs) < nPieces {
|
||||||
|
state.cache.pendingSlotLocs = make([]VarLoc, nPieces)
|
||||||
|
}
|
||||||
|
psl := state.cache.pendingSlotLocs[:nPieces]
|
||||||
for i := range psl {
|
for i := range psl {
|
||||||
psl[i] = VarLoc{}
|
psl[i] = VarLoc{}
|
||||||
}
|
}
|
||||||
|
|
@ -225,10 +229,12 @@ func (state *debugState) initializeCache() {
|
||||||
state.cache.pendingEntries = make([]pendingEntry, len(state.vars))
|
state.cache.pendingEntries = make([]pendingEntry, len(state.vars))
|
||||||
}
|
}
|
||||||
pe := state.cache.pendingEntries[:len(state.vars)]
|
pe := state.cache.pendingEntries[:len(state.vars)]
|
||||||
for varID := range pe {
|
freePieceIdx := 0
|
||||||
|
for varID, slots := range state.varSlots {
|
||||||
pe[varID] = pendingEntry{
|
pe[varID] = pendingEntry{
|
||||||
pieces: state.cache.pendingSlotLocs[varID*len(state.slots) : (varID+1)*len(state.slots)],
|
pieces: state.cache.pendingSlotLocs[freePieceIdx : freePieceIdx+len(slots)],
|
||||||
}
|
}
|
||||||
|
freePieceIdx += len(slots)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -657,9 +663,8 @@ func (a partsByVarOffset) Swap(i, j int) { a.slotIDs[i], a.slotIDs[j] = a.slotID
|
||||||
type pendingEntry struct {
|
type pendingEntry struct {
|
||||||
present bool
|
present bool
|
||||||
startBlock, startValue ID
|
startBlock, startValue ID
|
||||||
// The location of each piece of the variable, indexed by *SlotID*,
|
// The location of each piece of the variable, in the same order as the
|
||||||
// even though only a few slots are used in each entry. This could be
|
// SlotIDs in varParts.
|
||||||
// improved by only storing the relevant slots.
|
|
||||||
pieces []VarLoc
|
pieces []VarLoc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -736,14 +741,14 @@ func (state *debugState) buildLocationLists(Ctxt *obj.Link, blockLocs []*BlockDe
|
||||||
|
|
||||||
if state.loggingEnabled {
|
if state.loggingEnabled {
|
||||||
var partStrs []string
|
var partStrs []string
|
||||||
for _, slot := range state.varSlots[varID] {
|
for i, slot := range state.varSlots[varID] {
|
||||||
partStrs = append(partStrs, fmt.Sprintf("%v@%v", state.slots[slot], state.LocString(pending.pieces[slot])))
|
partStrs = append(partStrs, fmt.Sprintf("%v@%v", state.slots[slot], state.LocString(pending.pieces[i])))
|
||||||
}
|
}
|
||||||
state.logf("Add entry for %v: \tb%vv%v-b%vv%v = \t%v\n", state.vars[varID], pending.startBlock, pending.startValue, endBlock, endValue, strings.Join(partStrs, " "))
|
state.logf("Add entry for %v: \tb%vv%v-b%vv%v = \t%v\n", state.vars[varID], pending.startBlock, pending.startValue, endBlock, endValue, strings.Join(partStrs, " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, slotID := range state.varSlots[varID] {
|
for i, slotID := range state.varSlots[varID] {
|
||||||
loc := pending.pieces[slotID]
|
loc := pending.pieces[i]
|
||||||
slot := state.slots[slotID]
|
slot := state.slots[slotID]
|
||||||
|
|
||||||
if !loc.absent() {
|
if !loc.absent() {
|
||||||
|
|
@ -795,8 +800,8 @@ func (state *debugState) buildLocationLists(Ctxt *obj.Link, blockLocs []*BlockDe
|
||||||
// Extend the previous entry if possible.
|
// Extend the previous entry if possible.
|
||||||
if pending.present {
|
if pending.present {
|
||||||
merge := true
|
merge := true
|
||||||
for _, slotID := range state.varSlots[varID] {
|
for i, slotID := range state.varSlots[varID] {
|
||||||
if !canMerge(pending.pieces[slotID], curLoc[slotID]) {
|
if !canMerge(pending.pieces[i], curLoc[slotID]) {
|
||||||
merge = false
|
merge = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -810,7 +815,9 @@ func (state *debugState) buildLocationLists(Ctxt *obj.Link, blockLocs []*BlockDe
|
||||||
pending.present = true
|
pending.present = true
|
||||||
pending.startBlock = v.Block.ID
|
pending.startBlock = v.Block.ID
|
||||||
pending.startValue = v.ID
|
pending.startValue = v.ID
|
||||||
copy(pending.pieces, curLoc)
|
for i, slot := range state.varSlots[varID] {
|
||||||
|
pending.pieces[i] = curLoc[slot]
|
||||||
|
}
|
||||||
return
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue