Skip to content

cmd/compile/internal/ssa: merge more loc lists #65006

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 15 additions & 16 deletions src/cmd/compile/internal/ssa/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -1210,29 +1210,26 @@ func (e *pendingEntry) clear() {
}
}

// canMerge reports whether a new location description is a superset
// of the (non-empty) pending location description, if so, the two
// can be merged (i.e., pending is still a valid and useful location
// description).
// canMerge reports whether pending and new would produce the same location when
// writing a location list entry.
func canMerge(pending, new VarLoc) bool {
if pending.absent() && new.absent() {
// If the two locations are the same, they can be trivially merged.
// This covers the case where both are absent.
if pending == new {
return true
}
if pending.absent() || new.absent() {
return false
}
// pending is not absent, therefore it has either a stack mapping,
// or registers, or both.
if pending.onStack() && pending.StackOffset != new.StackOffset {
// if pending has a stack offset, then new must also, and it
// must be the same (StackOffset encodes onStack).
return false
}
if pending.Registers&new.Registers != pending.Registers {
// There is at least one register in pending not mentioned in new.
return false
// Stack locations are preferred to registers, so if the new location is in
// the same place on the stack as the old one, keep it regardless of any
// registers.
if pending.onStack() {
return pending.StackOffset == new.StackOffset
}
return true
// See if the pending location's reported register still works for the new
// value.
return new.Registers != 0 && firstReg(pending.Registers) == firstReg(new.Registers)
}

// firstReg returns the first register in set that is present.
Expand Down Expand Up @@ -1473,6 +1470,8 @@ func (state *debugState) writePendingEntry(varID VarID, endBlock, endValue ID) {
slot := state.slots[slotID]

if !loc.absent() {
// Note that the choice to prefer stack locations to registers when
// both exist here affects the logic in canMerge.
if loc.onStack() {
if loc.stackOffsetValue() == 0 {
list = append(list, dwarf.DW_OP_call_frame_cfa)
Expand Down