Commit 9c854d65 authored by Heschi Kreinick's avatar Heschi Kreinick

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/92400Reviewed-by: default avatarDavid Chase <drchase@google.com>
parent a306341d
...@@ -214,10 +214,14 @@ func (state *debugState) initializeCache() { ...@@ -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() { ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment