// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ssa

import (
	"fmt"
	"math/bits"
	"strings"

	"cmd/compile/internal/abt"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/ssa/ssabase"
	"cmd/compile/internal/ssa/ssaop"
	"cmd/internal/dwarf"
	"cmd/internal/obj"
)

type BlockDebug struct {
	// State at the start and end of the block. These are initialized,
	// and updated from new information that flows on back edges.
	startState, endState abt.T
	// Use these to avoid excess work in the merge. If none of the
	// predecessors has changed since the last check, the old answer is
	// still good.
	lastCheckedTime, lastChangedTime int32
	// Whether the block had any changes to user variables at all.
	relevant bool
	// false until the block has been processed at least once. This
	// affects how the merge is done; the goal is to maximize sharing
	// and avoid allocation.
	everProcessed bool
}

var BlockEnd = &Value{
	ID:  -20000,
	Op:  ssaop.OpInvalid,
	Aux: StringToAux("BlockEnd"),
}

var BlockStart = &Value{
	ID:  -10000,
	Op:  ssaop.OpInvalid,
	Aux: StringToAux("BlockStart"),
}

type DebugState struct {
	// See FuncDebug.
	Slots    []LocalSlot
	Vars     []*ir.Name
	VarSlots [][]SlotID
	Lists    [][]LocListEntry

	// The user variable that each slot rolls up to, indexed by SlotID.
	SlotVars []VarID

	F             *Func
	LoggingLevel  int
	ConvergeCount int // testing; iterate over block debug state this many times
	Registers     []ssabase.Register
	StackOffset   func(LocalSlot) int32
	Ctxt          *obj.Link

	// The names (slots) associated with each value, indexed by Value ID.
	ValueNames [][]SlotID

	// The current state of whatever analysis is running.
	currentState StateAtPC
	changedVars  *SparseSet
	changedSlots *SparseSet

	// The pending location list entry for each user variable, indexed by VarID.
	pendingEntries []pendingEntry

	VarParts        map[*ir.Name][]SlotID
	blockDebug      []BlockDebug
	pendingSlotLocs []VarLoc
}

var FuncEnd = &Value{
	ID:  -30000,
	Op:  ssaop.OpInvalid,
	Aux: StringToAux("FuncEnd"),
}

// IsVarWantedForDebug returns true if the debug info for the node should
// be generated.
// For example, internal variables for range-over-func loops have little
// value to users, so we don't generate debug info for them.
func IsVarWantedForDebug(n ir.Node) bool {
	name := n.Sym().Name
	if len(name) > 0 && name[0] == '&' {
		name = name[1:]
	}
	if len(name) > 0 && name[0] == '#' {
		// #yield is used by delve.
		return strings.HasPrefix(name, "#yield")
	}
	return true
}

// LocListEntry represents a single entry in a location list.
// StartBlock/StartValue and EndBlock/EndValue are SSA coordinates
// that get resolved to PCs during final encoding.
type LocListEntry struct {
	StartBlock, StartValue ID
	EndBlock, EndValue     ID
	Expr                   []byte // DWARF location expression (DW_OP_*)
}

// RegisterSet is a bitmap of registers, indexed by Register.num.
type RegisterSet uint64

type SlotID int32

// StackOffset encodes whether a value is on the stack and if so, where.
// It is a 31-bit integer followed by a presence flag at the low-order
// bit.
type StackOffset int32

// StateAtPC is the current state of all variables at some point.
type StateAtPC struct {
	// The location of each known slot, indexed by SlotID.
	slots []VarLoc
	// The slots present in each register, indexed by register number.
	registers [][]SlotID
}

type VarID int32

// A VarLoc describes the storage for part of a user variable.
type VarLoc struct {
	// The registers this variable is available in. There can be more than
	// one in various situations, e.g. it's being moved between registers.
	Registers RegisterSet

	StackOffset
}

// 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).
func canMerge(pending, new VarLoc) bool {
	if pending.absent() && new.absent() {
		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
	}
	return true
}

// firstReg returns the first register in set that is present.
func firstReg(set RegisterSet) uint8 {
	if set == 0 {
		// This is wrong, but there seem to be some situations where we
		// produce locations with no storage.
		return 0
	}
	return uint8(bits.TrailingZeros64(uint64(set)))
}

// A liveSlot is a slot that's live in loc at entry/exit of a block.
type liveSlot struct {
	VarLoc
}

// A pendingEntry represents the beginning of a location list entry, missing
// only its end coordinate.
type pendingEntry struct {
	present                bool
	startBlock, startValue ID
	// The location of each piece of the variable, in the same order as the
	// SlotIDs in varParts.
	pieces []VarLoc
}

func (ls *liveSlot) String() string {
	return fmt.Sprintf("0x%x.%d.%d", ls.Registers, ls.stackOffsetValue(), int32(ls.StackOffset)&1)
}

func (s StackOffset) onStack() bool {
	return s != 0
}

func (s StackOffset) stackOffsetValue() int32 {
	return int32(s) >> 1
}

// reset fills state with the live variables from live.
func (state *StateAtPC) reset(live abt.T) {
	slots, registers := state.slots, state.registers
	clear(slots)
	for i := range registers {
		registers[i] = registers[i][:0]
	}
	for it := live.Iterator(); !it.Done(); {
		k, d := it.Next()
		live := d.(*liveSlot)
		slots[k] = live.VarLoc
		if live.VarLoc.Registers == 0 {
			continue
		}

		mask := uint64(live.VarLoc.Registers)
		for {
			if mask == 0 {
				break
			}
			reg := uint8(bits.TrailingZeros64(mask))
			mask &^= 1 << reg

			registers[reg] = append(registers[reg], SlotID(k))
		}
	}
	state.slots, state.registers = slots, registers
}

func (s *DebugState) LocString(loc VarLoc) string {
	if loc.absent() {
		return "<nil>"
	}

	var storage []string
	if loc.onStack() {
		storage = append(storage, fmt.Sprintf("@%+d", loc.stackOffsetValue()))
	}

	mask := uint64(loc.Registers)
	for {
		if mask == 0 {
			break
		}
		reg := uint8(bits.TrailingZeros64(mask))
		mask &^= 1 << reg

		storage = append(storage, s.Registers[reg].String())
	}
	return strings.Join(storage, ",")
}

func (loc VarLoc) absent() bool {
	return loc.Registers == 0 && !loc.onStack()
}

func (loc VarLoc) intersect(other VarLoc) VarLoc {
	if !loc.onStack() || !other.onStack() || loc.StackOffset != other.StackOffset {
		loc.StackOffset = 0
	}
	loc.Registers &= other.Registers
	return loc
}

// Logf prints debug-specific logging to stdout (always stdout) if the
// current function is tagged by GOSSAFUNC (for ssa output directed
// either to stdout or html).
func (s *DebugState) Logf(msg string, args ...any) {
	if s.F.PrintOrHtmlSSA {
		fmt.Printf(msg, args...)
	}
}

func (state *DebugState) InitializeCache(f *Func, numVars, numSlots int) {
	// One blockDebug per block. Initialized in allocBlock.
	if cap(state.blockDebug) < f.NumBlocks() {
		state.blockDebug = make([]BlockDebug, f.NumBlocks())
	} else {
		clear(state.blockDebug[:f.NumBlocks()])
	}

	// A list of slots per Value. Reuse the previous child slices.
	if cap(state.ValueNames) < f.NumValues() {
		old := state.ValueNames
		state.ValueNames = make([][]SlotID, f.NumValues())
		copy(state.ValueNames, old)
	}
	vn := state.ValueNames[:f.NumValues()]
	for i := range vn {
		vn[i] = vn[i][:0]
	}

	// Slot and register contents for currentState. Cleared by reset().
	if cap(state.currentState.slots) < numSlots {
		state.currentState.slots = make([]VarLoc, numSlots)
	} else {
		state.currentState.slots = state.currentState.slots[:numSlots]
	}
	if cap(state.currentState.registers) < len(state.Registers) {
		state.currentState.registers = make([][]SlotID, len(state.Registers))
	} else {
		state.currentState.registers = state.currentState.registers[:len(state.Registers)]
	}

	// A relatively small slice, but used many times as the return from processValue.
	state.changedVars = NewSparseSet(numVars)
	state.changedSlots = NewSparseSet(numSlots)

	// A pending entry per user variable, with space to track each of its pieces.
	numPieces := 0
	for i := range state.VarSlots {
		numPieces += len(state.VarSlots[i])
	}
	if cap(state.pendingSlotLocs) < numPieces {
		state.pendingSlotLocs = make([]VarLoc, numPieces)
	} else {
		clear(state.pendingSlotLocs[:numPieces])
	}
	if cap(state.pendingEntries) < numVars {
		state.pendingEntries = make([]pendingEntry, numVars)
	}
	pe := state.pendingEntries[:numVars]
	freePieceIdx := 0
	for varID, slots := range state.VarSlots {
		pe[varID] = pendingEntry{
			pieces: state.pendingSlotLocs[freePieceIdx : freePieceIdx+len(slots)],
		}
		freePieceIdx += len(slots)
	}
	state.pendingEntries = pe

	if cap(state.Lists) < numVars {
		state.Lists = make([][]LocListEntry, numVars)
	} else {
		state.Lists = state.Lists[:numVars]
		clear(state.Lists)
	}
}

func (state *DebugState) allocBlock(b *Block) *BlockDebug {
	return &state.blockDebug[b.ID]
}

func (s *DebugState) blockEndStateString(b *BlockDebug) string {
	endState := StateAtPC{slots: make([]VarLoc, len(s.Slots)), registers: make([][]SlotID, len(s.Registers))}
	endState.reset(b.endState)
	return s.stateString(endState)
}

func (s *DebugState) stateString(state StateAtPC) string {
	var strs []string
	for slotID, loc := range state.slots {
		if !loc.absent() {
			strs = append(strs, fmt.Sprintf("\t%v = %v\n", s.Slots[slotID], s.LocString(loc)))
		}
	}

	strs = append(strs, "\n")
	for reg, slots := range state.registers {
		if len(slots) != 0 {
			var slotStrs []string
			for _, slot := range slots {
				slotStrs = append(slotStrs, s.Slots[slot].String())
			}
			strs = append(strs, fmt.Sprintf("\t%v = %v\n", &s.Registers[reg], slotStrs))
		}
	}

	if len(strs) == 1 {
		return "(no vars)\n"
	}
	return strings.Join(strs, "")
}

// Liveness walks the function in control flow order, calculating the start
// and end state of each block.
func (state *DebugState) Liveness() []*BlockDebug {
	blockLocs := make([]*BlockDebug, state.F.NumBlocks())
	counterTime := int32(1)

	// Reverse postorder: visit a block after as many as possible of its
	// predecessors have been visited.
	po := state.F.Postorder()
	converged := false

	// The iteration rule is that by default, run until converged, but
	// if a particular iteration count is specified, run that many
	// iterations, no more, no less.  A count is specified as the
	// thousands digit of the location lists debug flag,
	// e.g. -d=locationlists=4000
	keepGoing := func(k int) bool {
		if state.ConvergeCount == 0 {
			return !converged
		}
		return k < state.ConvergeCount
	}
	for k := 0; keepGoing(k); k++ {
		if state.LoggingLevel > 0 {
			state.Logf("Liveness pass %d\n", k)
		}
		converged = true
		for i := len(po) - 1; i >= 0; i-- {
			b := po[i]
			locs := blockLocs[b.ID]
			if locs == nil {
				locs = state.allocBlock(b)
				blockLocs[b.ID] = locs
			}

			// Build the starting state for the block from the final
			// state of its predecessors.
			startState, blockChanged := state.mergePredecessors(b, blockLocs, nil, false)
			locs.lastCheckedTime = counterTime
			counterTime++
			if state.LoggingLevel > 1 {
				state.Logf("Processing %v, block changed %v, initial state:\n%v", b, blockChanged, state.stateString(state.currentState))
			}

			if blockChanged {
				// If the start did not change, then the old endState is good
				converged = false
				changed := false
				state.changedSlots.Clear()

				// Update locs/registers with the effects of each Value.
				for _, v := range b.Values {
					slots := state.ValueNames[v.ID]

					// Loads and stores inherit the names of their sources.
					var source *Value
					switch v.Op {
					case ssaop.OpStoreReg:
						source = v.Args[0]
					case ssaop.OpLoadReg:
						switch a := v.Args[0]; a.Op {
						case ssaop.OpArg, ssaop.OpPhi:
							source = a
						case ssaop.OpStoreReg:
							source = a.Args[0]
						default:
							if state.LoggingLevel > 1 {
								state.Logf("at %v: load with unexpected source op: %v (%v)\n", v, a.Op, a)
							}
						}
					}
					// Update valueNames with the source so that later steps
					// don't need special handling.
					if source != nil && k == 0 {
						// limit to k == 0 otherwise there are duplicates.
						slots = append(slots, state.ValueNames[source.ID]...)
						state.ValueNames[v.ID] = slots
					}

					reg, _ := state.F.GetHome(v.ID).(*ssabase.Register)
					c := state.processValue(v, slots, reg)
					changed = changed || c
				}

				if state.LoggingLevel > 1 {
					state.Logf("Block %v done, locs:\n%v", b, state.stateString(state.currentState))
				}

				locs.relevant = locs.relevant || changed
				if !changed {
					locs.endState = startState
				} else {
					for _, id := range state.changedSlots.Contents() {
						slotID := SlotID(id)
						slotLoc := state.currentState.slots[slotID]
						if slotLoc.absent() {
							startState.Delete(int32(slotID))
							continue
						}
						old := startState.Find(int32(slotID)) // do NOT replace existing values
						if oldLS, ok := old.(*liveSlot); !ok || oldLS.VarLoc != slotLoc {
							startState.Insert(int32(slotID),
								&liveSlot{VarLoc: slotLoc})
						}
					}
					locs.endState = startState
				}
				locs.lastChangedTime = counterTime
			}
			counterTime++
		}
	}
	return blockLocs
}

// mergePredecessors takes the end state of each of b's predecessors and
// intersects them to form the starting state for b. It puts that state
// in blockLocs[b.ID].startState, and fills state.currentState with it.
// It returns the start state and whether this is changed from the
// previously approximated value of startState for this block.  After
// the first call, subsequent calls can only shrink startState.
//
// Passing forLocationLists=true enables additional side-effects that
// are necessary for building location lists but superfluous while still
// iterating to an answer.
//
// If previousBlock is non-nil, it registers changes vs. that block's
// end state in state.changedVars. Note that previousBlock will often
// not be a predecessor.
//
// Note that mergePredecessors behaves slightly differently between
// first and subsequent calls for a block.  For the first call, the
// starting state is approximated by taking the state from the
// predecessor whose state is smallest, and removing any elements not
// in all the other predecessors; this makes the smallest number of
// changes and shares the most state.  On subsequent calls the old
// value of startState is adjusted with new information; this is judged
// to do the least amount of extra work.
//
// To improve performance, each block's state information is marked with
// lastChanged and lastChecked "times" so unchanged predecessors can be
// skipped on after-the-first iterations.  Doing this allows extra
// iterations by the caller to be almost free.
//
// It is important to know that the set representation used for
// startState, endState, and merges can share data for two sets where
// one is a small delta from the other.  Doing this does require a
// little care in how sets are updated, both in mergePredecessors, and
// using its result.
func (state *DebugState) mergePredecessors(b *Block, blockLocs []*BlockDebug, previousBlock *Block, forLocationLists bool) (abt.T, bool) {
	// Filter out back branches.
	var predsBuf [10]*Block

	preds := predsBuf[:0]
	locs := blockLocs[b.ID]

	blockChanged := !locs.everProcessed // the first time it always changes.
	updating := locs.everProcessed

	// For the first merge, exclude predecessors that have not been seen yet.
	// I.e., backedges.
	for _, pred := range b.Preds {
		if bl := blockLocs[pred.B.ID]; bl != nil && bl.everProcessed {
			// crucially, a self-edge has bl != nil, but bl.everProcessed is false the first time.
			preds = append(preds, pred.B)
		}
	}

	locs.everProcessed = true

	if state.LoggingLevel > 1 {
		// The logf below would cause preds to be heap-allocated if
		// it were passed directly.
		preds2 := make([]*Block, len(preds))
		copy(preds2, preds)
		state.Logf("Merging %v into %v (changed=%d, checked=%d)\n", preds2, b, locs.lastChangedTime, locs.lastCheckedTime)
	}

	state.changedVars.Clear()

	markChangedVars := func(slots, merged abt.T) {
		if !forLocationLists {
			return
		}
		// Fill changedVars with those that differ between the previous
		// block (in the emit order, not necessarily a flow predecessor)
		// and the start state for this block.
		for it := slots.Iterator(); !it.Done(); {
			k, v := it.Next()
			m := merged.Find(k)
			if m == nil || v.(*liveSlot).VarLoc != m.(*liveSlot).VarLoc {
				state.changedVars.Add(ID(state.SlotVars[k]))
			}
		}
	}

	reset := func(ourStartState abt.T) {
		if !(forLocationLists || blockChanged) {
			// there is no change and this is not for location lists, do
			// not bother to reset currentState because it will not be
			// examined.
			return
		}
		state.currentState.reset(ourStartState)
	}

	// Zero predecessors
	if len(preds) == 0 {
		if previousBlock != nil {
			state.F.Fatalf("Function %v, block %s with no predecessors is not first block, has previous %s", state.F, b.String(), previousBlock.String())
		}
		// startState is empty
		reset(abt.T{})
		return abt.T{}, blockChanged
	}

	// One predecessor
	l0 := blockLocs[preds[0].ID]
	p0 := l0.endState
	if len(preds) == 1 {
		if previousBlock != nil && preds[0].ID != previousBlock.ID {
			// Change from previous block is its endState minus the predecessor's endState
			markChangedVars(blockLocs[previousBlock.ID].endState, p0)
		}
		locs.startState = p0
		blockChanged = blockChanged || l0.lastChangedTime > locs.lastCheckedTime
		reset(p0)
		return p0, blockChanged
	}

	// More than one predecessor

	if updating {
		// After the first approximation, i.e., when updating, results
		// can only get smaller, because initially backedge
		// predecessors do not participate in the intersection.  This
		// means that for the update, given the prior approximation of
		// startState, there is no need to re-intersect with unchanged
		// blocks.  Therefore remove unchanged blocks from the
		// predecessor list.
		for i := len(preds) - 1; i >= 0; i-- {
			pred := preds[i]
			if blockLocs[pred.ID].lastChangedTime > locs.lastCheckedTime {
				continue // keep this predecessor
			}
			preds[i] = preds[len(preds)-1]
			preds = preds[:len(preds)-1]
			if state.LoggingLevel > 2 {
				state.Logf("Pruned b%d, lastChanged was %d but b%d lastChecked is %d\n", pred.ID, blockLocs[pred.ID].lastChangedTime, b.ID, locs.lastCheckedTime)
			}
		}
		// Check for an early out; this should always hit for the update
		// if there are no cycles.
		if len(preds) == 0 {
			blockChanged = false

			reset(locs.startState)
			if state.LoggingLevel > 2 {
				state.Logf("Early out, no predecessors changed since last check\n")
			}
			if previousBlock != nil {
				markChangedVars(blockLocs[previousBlock.ID].endState, locs.startState)
			}
			return locs.startState, blockChanged
		}
	}

	baseID := preds[0].ID
	baseState := p0

	// Choose the predecessor with the smallest endState for intersection work
	for _, pred := range preds[1:] {
		if blockLocs[pred.ID].endState.Size() < baseState.Size() {
			baseState = blockLocs[pred.ID].endState
			baseID = pred.ID
		}
	}

	if state.LoggingLevel > 2 {
		state.Logf("Starting %v with state from b%v:\n%v", b, baseID, state.blockEndStateString(blockLocs[baseID]))
		for _, pred := range preds {
			if pred.ID == baseID {
				continue
			}
			state.Logf("Merging in state from %v:\n%v", pred, state.blockEndStateString(blockLocs[pred.ID]))
		}
	}

	state.currentState.reset(abt.T{})
	// The normal logic of "reset" is included in the intersection loop below.

	slotLocs := state.currentState.slots

	// If this is the first call, do updates on the "baseState"; if this
	// is a subsequent call, tweak the startState instead. Note that
	// these "set" values are values; there are no side effects to
	// other values as these are modified.
	newState := baseState
	if updating {
		newState = blockLocs[b.ID].startState
	}

	for it := newState.Iterator(); !it.Done(); {
		k, d := it.Next()
		thisSlot := d.(*liveSlot)
		x := thisSlot.VarLoc
		x0 := x // initial value in newState

		// Intersect this slot with the slot in all the predecessors
		for _, other := range preds {
			if !updating && other.ID == baseID {
				continue
			}
			otherSlot := blockLocs[other.ID].endState.Find(k)
			if otherSlot == nil {
				x = VarLoc{}
				break
			}
			y := otherSlot.(*liveSlot).VarLoc
			x = x.intersect(y)
			if x.absent() {
				x = VarLoc{}
				break
			}
		}

		// Delete if necessary, but not otherwise (in order to maximize sharing).
		if x.absent() {
			if !x0.absent() {
				blockChanged = true
				newState.Delete(k)
			}
			slotLocs[k] = VarLoc{}
			continue
		}
		if x != x0 {
			blockChanged = true
			newState.Insert(k, &liveSlot{VarLoc: x})
		}

		slotLocs[k] = x
		mask := uint64(x.Registers)
		for {
			if mask == 0 {
				break
			}
			reg := uint8(bits.TrailingZeros64(mask))
			mask &^= 1 << reg
			state.currentState.registers[reg] = append(state.currentState.registers[reg], SlotID(k))
		}
	}

	if previousBlock != nil {
		markChangedVars(blockLocs[previousBlock.ID].endState, newState)
	}
	locs.startState = newState
	return newState, blockChanged
}

// processValue updates locs and state.registerContents to reflect v, a
// value with the names in vSlots and homed in vReg.  "v" becomes
// visible after execution of the instructions evaluating it. It
// returns which VarIDs were modified by the Value's execution.
func (state *DebugState) processValue(v *Value, vSlots []SlotID, vReg *ssabase.Register) bool {
	locs := state.currentState
	changed := false
	setSlot := func(slot SlotID, loc VarLoc) {
		changed = true
		state.changedVars.Add(ID(state.SlotVars[slot]))
		state.changedSlots.Add(ID(slot))
		state.currentState.slots[slot] = loc
	}

	// Handle any register clobbering. Call operations, for example,
	// clobber all registers even though they don't explicitly write to
	// them.
	clobbers := ssaop.OpcodeTable[v.Op].Reg.Clobbers
	for {
		if clobbers.Empty() {
			break
		}
		reg := clobbers.PickReg()
		clobbers = clobbers.RemoveReg(reg)

		for _, slot := range locs.registers[reg] {
			if state.LoggingLevel > 1 {
				state.Logf("at %v: %v clobbered out of %v\n", v, state.Slots[slot], &state.Registers[reg])
			}

			last := locs.slots[slot]
			if last.absent() {
				state.F.Fatalf("at %v: slot %v in register %v with no location entry", v, state.Slots[slot], &state.Registers[reg])
				continue
			}
			regs := last.Registers &^ (1 << reg)
			setSlot(slot, VarLoc{regs, last.StackOffset})
		}

		locs.registers[reg] = locs.registers[reg][:0]
	}

	switch {
	case v.Op == ssaop.OpVarDef:
		n := v.Aux.(*ir.Name)
		if ir.IsSynthetic(n) || !IsVarWantedForDebug(n) {
			break
		}

		slotID := state.VarParts[n][0]
		var stackOffset StackOffset
		if v.Op == ssaop.OpVarDef {
			stackOffset = StackOffset(state.StackOffset(state.Slots[slotID])<<1 | 1)
		}
		setSlot(slotID, VarLoc{0, stackOffset})
		if state.LoggingLevel > 1 {
			if v.Op == ssaop.OpVarDef {
				state.Logf("at %v: stack-only var %v now live\n", v, state.Slots[slotID])
			} else {
				state.Logf("at %v: stack-only var %v now dead\n", v, state.Slots[slotID])
			}
		}

	case v.Op == ssaop.OpArg:
		home := state.F.GetHome(v.ID).(LocalSlot)
		stackOffset := state.StackOffset(home)<<1 | 1
		for _, slot := range vSlots {
			if state.LoggingLevel > 1 {
				state.Logf("at %v: arg %v now on stack in location %v\n", v, state.Slots[slot], home)
				if last := locs.slots[slot]; !last.absent() {
					state.Logf("at %v: unexpected arg op on already-live slot %v\n", v, state.Slots[slot])
				}
			}

			setSlot(slot, VarLoc{0, StackOffset(stackOffset)})
		}

	case v.Op == ssaop.OpStoreReg:
		home := state.F.GetHome(v.ID).(LocalSlot)
		stackOffset := state.StackOffset(home)<<1 | 1
		for _, slot := range vSlots {
			last := locs.slots[slot]
			if last.absent() {
				if state.LoggingLevel > 1 {
					state.Logf("at %v: unexpected spill of unnamed register %s\n", v, vReg)
				}
				break
			}

			setSlot(slot, VarLoc{last.Registers, StackOffset(stackOffset)})
			if state.LoggingLevel > 1 {
				state.Logf("at %v: %v spilled to stack location %v@%d\n", v, state.Slots[slot], home, state.StackOffset(home))
			}
		}

	case vReg != nil:
		if state.LoggingLevel > 1 {
			newSlots := make([]bool, len(state.Slots))
			for _, slot := range vSlots {
				newSlots[slot] = true
			}

			for _, slot := range locs.registers[vReg.Num] {
				if !newSlots[slot] {
					state.Logf("at %v: overwrote %v in register %v\n", v, state.Slots[slot], vReg)
				}
			}
		}

		for _, slot := range locs.registers[vReg.Num] {
			last := locs.slots[slot]
			setSlot(slot, VarLoc{last.Registers &^ (1 << uint8(vReg.Num)), last.StackOffset})
		}
		locs.registers[vReg.Num] = locs.registers[vReg.Num][:0]
		locs.registers[vReg.Num] = append(locs.registers[vReg.Num], vSlots...)
		for _, slot := range vSlots {
			if state.LoggingLevel > 1 {
				state.Logf("at %v: %v now in %s\n", v, state.Slots[slot], vReg)
			}

			last := locs.slots[slot]
			setSlot(slot, VarLoc{1<<uint8(vReg.Num) | last.Registers, last.StackOffset})
		}
	}
	return changed
}

func (e *pendingEntry) clear() {
	e.present = false
	e.startBlock = 0
	e.startValue = 0
	clear(e.pieces)
}

// BuildLocationLists builds location lists for all the user variables
// in state.f, using the information about block state in blockLocs.
// The returned location lists are not fully complete. They are in
// terms of SSA values rather than PCs, and have no base address/end
// entries. They will be finished by PutLocationList.
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.

	var prevBlock *Block
	for _, b := range state.F.Blocks {
		state.mergePredecessors(b, blockLocs, prevBlock, true)

		// Handle any differences among predecessor blocks and previous block (perhaps not a predecessor)
		for _, varID := range state.changedVars.Contents() {
			state.updateVar(VarID(varID), b, BlockStart)
		}
		state.changedVars.Clear()

		if !blockLocs[b.ID].relevant {
			continue
		}

		mustBeFirst := func(v *Value) bool {
			return v.Op == ssaop.OpPhi || v.Op.IsLoweredGetClosurePtr() ||
				v.Op == ssaop.OpArgIntReg || v.Op == ssaop.OpArgFloatReg
		}

		blockPrologComplete := func(v *Value) bool {
			if b.ID != state.F.Entry.ID {
				return !ssaop.OpcodeTable[v.Op].ZeroWidth
			} else {
				return v.Op == ssaop.OpInitMem
			}
		}

		// Examine the prolog portion of the block to process special
		// zero-width ops such as Arg, Phi, LoweredGetClosurePtr (etc)
		// whose lifetimes begin at the block starting point. In an
		// entry block, allow for the possibility that we may see Arg
		// ops that appear _after_ other non-zero-width operations.
		// Example:
		//
		//   v33 = ArgIntReg <uintptr> {foo+0} [0] : AX (foo)
		//   v34 = ArgIntReg <uintptr> {bar+0} [0] : BX (bar)
		//   ...
		//   v77 = StoreReg <unsafe.Pointer> v67 : ctx+8[unsafe.Pointer]
		//   v78 = StoreReg <unsafe.Pointer> v68 : ctx[unsafe.Pointer]
		//   v79 = Arg <*uint8> {args} : args[*uint8] (args[*uint8])
		//   v80 = Arg <int> {args} [8] : args+8[int] (args+8[int])
		//   ...
		//   v1 = InitMem <mem>
		//
		// We can stop scanning the initial portion of the block when
		// we either see the InitMem op (for entry blocks) or the
		// first non-zero-width op (for other blocks).
		for idx := 0; idx < len(b.Values); idx++ {
			v := b.Values[idx]
			if blockPrologComplete(v) {
				break
			}
			// Consider only "lifetime begins at block start" ops.
			if !mustBeFirst(v) && v.Op != ssaop.OpArg {
				continue
			}
			slots := state.ValueNames[v.ID]
			reg, _ := state.F.GetHome(v.ID).(*ssabase.Register)
			changed := state.processValue(v, slots, reg) // changed == added to state.changedVars
			if changed {
				for _, varID := range state.changedVars.Contents() {
					state.updateVar(VarID(varID), v.Block, BlockStart)
				}
				state.changedVars.Clear()
			}
		}

		// Now examine the block again, handling things other than the
		// "begins at block start" lifetimes.
		zeroWidthPending := false
		prologComplete := false
		// expect to see values in pattern (apc)* (zerowidth|real)*
		for _, v := range b.Values {
			if blockPrologComplete(v) {
				prologComplete = true
			}
			slots := state.ValueNames[v.ID]
			reg, _ := state.F.GetHome(v.ID).(*ssabase.Register)
			changed := state.processValue(v, slots, reg) // changed == added to state.changedVars

			if ssaop.OpcodeTable[v.Op].ZeroWidth {
				if prologComplete && mustBeFirst(v) {
					panic(fmt.Errorf("Unexpected placement of op '%s' appearing after non-pseudo-op at beginning of block %s in %s\n%s", v.LongString(), b, b.Func.Name, b.Func))
				}
				if changed {
					if mustBeFirst(v) || v.Op == ssaop.OpArg {
						// already taken care of above
						continue
					}
					zeroWidthPending = true
				}
				continue
			}
			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.Block, v)
			}
			state.changedVars.Clear()
		}
		for _, varID := range state.changedVars.Contents() {
			state.updateVar(VarID(varID), b, BlockEnd)
		}

		prevBlock = b
	}

	if state.LoggingLevel > 0 {
		state.Logf("location lists:\n")
	}

	// Flush any leftover entries live at the end of the last block.
	for varID := range state.Lists {
		state.writePendingEntry(VarID(varID), -1, FuncEnd.ID)
		list := state.Lists[varID]
		if state.LoggingLevel > 0 {
			if len(list) == 0 {
				state.Logf("\t%v : empty list\n", state.Vars[varID])
			} else {
				state.Logf("\t%v : %d entries\n", state.Vars[varID], len(list))
			}
		}
	}
}

// updateVar updates the pending location list entry for varID to
// 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] {
		if !curLoc[slotID].absent() {
			empty = false
			break
		}
	}
	pending := &state.pendingEntries[varID]
	if empty {
		state.writePendingEntry(varID, b.ID, v.ID)
		pending.clear()
		return
	}

	// Extend the previous entry if possible.
	if pending.present {
		merge := true
		for i, slotID := range state.VarSlots[varID] {
			if !canMerge(pending.pieces[i], curLoc[slotID]) {
				merge = false
				break
			}
		}
		if merge {
			return
		}
	}

	state.writePendingEntry(varID, b.ID, v.ID)
	pending.present = true
	pending.startBlock = b.ID
	pending.startValue = v.ID
	for i, slot := range state.VarSlots[varID] {
		pending.pieces[i] = curLoc[slot]
	}
}

// writePendingEntry writes out the pending entry for varID, if any,
// terminated at endBlock/Value.
func (state *DebugState) writePendingEntry(varID VarID, endBlock, endValue ID) {
	pending := state.pendingEntries[varID]
	if !pending.present {
		return
	}

	// Skip zero-width entries where start and end coordinates are identical.
	if pending.startBlock == endBlock && pending.startValue == endValue {
		if state.LoggingLevel > 1 {
			state.Logf("Skipping empty location list for %v in %s\n", state.Vars[varID], state.F.Name)
		}
		return
	}

	if state.LoggingLevel > 1 {
		var partStrs []string
		for i, slot := range state.VarSlots[varID] {
			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, " "))
	}

	// Build the DWARF location expression.
	var expr []byte
	for i, slotID := range state.VarSlots[varID] {
		loc := pending.pieces[i]
		slot := state.Slots[slotID]

		if !loc.absent() {
			if loc.onStack() {
				if loc.stackOffsetValue() == 0 {
					expr = append(expr, dwarf.DW_OP_call_frame_cfa)
				} else {
					expr = append(expr, dwarf.DW_OP_fbreg)
					expr = dwarf.AppendSleb128(expr, int64(loc.stackOffsetValue()))
				}
			} else {
				regnum := state.Ctxt.Arch.DWARFRegisters[state.Registers[firstReg(loc.Registers)].ObjNum]
				if regnum < 32 {
					expr = append(expr, dwarf.DW_OP_reg0+byte(regnum))
				} else {
					expr = append(expr, dwarf.DW_OP_regx)
					expr = dwarf.AppendUleb128(expr, uint64(regnum))
				}
			}
		}

		if len(state.VarSlots[varID]) > 1 {
			expr = append(expr, dwarf.DW_OP_piece)
			expr = dwarf.AppendUleb128(expr, uint64(slot.Type.Size()))
		}
	}

	entry := LocListEntry{
		StartBlock: pending.startBlock,
		StartValue: pending.startValue,
		EndBlock:   endBlock,
		EndValue:   endValue,
		Expr:       expr,
	}
	state.Lists[varID] = append(state.Lists[varID], entry)
}
