diff options
author | David Chase <drchase@google.com> | 2018-10-26 12:00:07 -0400 |
---|---|---|
committer | David Chase <drchase@google.com> | 2018-11-29 14:00:26 +0000 |
commit | 2b58ca6e3de3d93817a4e6cc55378015eb3c2040 (patch) | |
tree | 0f255bde39d3a544ec1ac6b1ea62a752f0c7a796 /src/cmd/compile/internal/ssa/debug.go | |
parent | 311d87dbebbb0238196d3aa13fd9a37f655e1fc3 (diff) | |
download | go-2b58ca6e3de3d93817a4e6cc55378015eb3c2040.tar.gz go-2b58ca6e3de3d93817a4e6cc55378015eb3c2040.zip |
cmd/compile: begin OpArg and OpPhi location lists at block start
For the entry block, make the "first instruction" be truly
the first instruction. This allows printing of incoming
parameters with Delve.
Also be sure Phis are marked as being at the start of their
block. This is observed to move location list pointers,
and where moved, they become correct.
Leading zero-width instructions include LoweredGetClosurePtr.
Because this instruction is actually architecture-specific,
and it is now tested for in 3 different places, also created
Op.isLoweredGetClosurePtr() to reduce future surprises.
Change-Id: Ic043b7265835cf1790382a74334b5714ae4060af
Reviewed-on: https://go-review.googlesource.com/c/145179
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/debug.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/debug.go | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/src/cmd/compile/internal/ssa/debug.go b/src/cmd/compile/internal/ssa/debug.go index 3d0be0fe1c..b6c25f6573 100644 --- a/src/cmd/compile/internal/ssa/debug.go +++ b/src/cmd/compile/internal/ssa/debug.go @@ -826,6 +826,7 @@ func firstReg(set RegisterSet) uint8 { func (state *debugState) buildLocationLists(blockLocs []*BlockDebug) { // Run through the function in program text order, building up location // lists as we go. The heavy lifting has mostly already been done. + for _, b := range state.f.Blocks { if !blockLocs[b.ID].relevant { continue @@ -834,13 +835,24 @@ func (state *debugState) buildLocationLists(blockLocs []*BlockDebug) { state.mergePredecessors(b, blockLocs) zeroWidthPending := false + apcChangedSize := 0 // size of changedVars for leading Args, Phi, ClosurePtr + // expect to see values in pattern (apc)* (zerowidth|real)* for _, v := range b.Values { slots := state.valueNames[v.ID] reg, _ := state.f.getHome(v.ID).(*Register) - changed := state.processValue(v, slots, reg) + changed := state.processValue(v, slots, reg) // changed == added to state.changedVars if opcodeTable[v.Op].zeroWidth { if changed { + if v.Op == OpArg || v.Op == OpPhi || v.Op.isLoweredGetClosurePtr() { + // These ranges begin at true beginning of block, not after first instruction + if zeroWidthPending { + b.Func.Fatalf("Unexpected op mixed with OpArg/OpPhi/OpLoweredGetClosurePtr at beginning of block %s in %s\n%s", b, b.Func.Name, b.Func) + } + apcChangedSize = len(state.changedVars.contents()) + continue + } + // Other zero-width ops must wait on a "real" op. zeroWidthPending = true } continue @@ -849,12 +861,25 @@ func (state *debugState) buildLocationLists(blockLocs []*BlockDebug) { if !changed && !zeroWidthPending { continue } + // Not zero-width; i.e., a "real" instruction. zeroWidthPending = false - for _, varID := range state.changedVars.contents() { - state.updateVar(VarID(varID), v, state.currentState.slots) + for i, varID := range state.changedVars.contents() { + if i < apcChangedSize { // buffered true start-of-block changes + state.updateVar(VarID(varID), v.Block, BlockStart) + } else { + state.updateVar(VarID(varID), v.Block, v) + } } state.changedVars.clear() + apcChangedSize = 0 + } + for i, varID := range state.changedVars.contents() { + if i < apcChangedSize { // buffered true start-of-block changes + state.updateVar(VarID(varID), b, BlockStart) + } else { + state.updateVar(VarID(varID), b, BlockEnd) + } } } @@ -877,8 +902,10 @@ func (state *debugState) buildLocationLists(blockLocs []*BlockDebug) { } // updateVar updates the pending location list entry for varID to -// reflect the new locations in curLoc, caused by v. -func (state *debugState) updateVar(varID VarID, v *Value, curLoc []VarLoc) { +// reflect the new locations in curLoc, beginning at v in block b. +// v may be one of the special values indicating block start or end. +func (state *debugState) updateVar(varID VarID, b *Block, v *Value) { + curLoc := state.currentState.slots // Assemble the location list entry with whatever's live. empty := true for _, slotID := range state.varSlots[varID] { @@ -889,7 +916,7 @@ func (state *debugState) updateVar(varID VarID, v *Value, curLoc []VarLoc) { } pending := &state.pendingEntries[varID] if empty { - state.writePendingEntry(varID, v.Block.ID, v.ID) + state.writePendingEntry(varID, b.ID, v.ID) pending.clear() return } @@ -908,9 +935,9 @@ func (state *debugState) updateVar(varID VarID, v *Value, curLoc []VarLoc) { } } - state.writePendingEntry(varID, v.Block.ID, v.ID) + state.writePendingEntry(varID, b.ID, v.ID) pending.present = true - pending.startBlock = v.Block.ID + pending.startBlock = b.ID pending.startValue = v.ID for i, slot := range state.varSlots[varID] { pending.pieces[i] = curLoc[slot] |